我能在C#中内联使用async/await吗?

9 浏览
0 Comments

我能在C#中内联使用async/await吗?

我有一个代码块,可以异步地运行一些内容。我如何使LongOperation()以"内联"的方式异步运行(直接从Main方法中)而不创建LongTask()和LongOperationAsync()函数?

class Program
{
    static void Main(string[] args)
    {
        LongOperationAsync();
        Console.WriteLine("主线程已完成。");
        Console.ReadKey();     
    }
    static void LongOperation()
    {
        Thread.Sleep(3000);
        Console.WriteLine("工作已完成");
    }
    static Task LongTask()
    {
        return Task.Run(() => LongOperation());
    }
    static async void LongOperationAsync()
    {
        await LongTask();
        Console.WriteLine("回调已触发");
    }
}

更新:

我希望我做得对。我的意思是,我想使任何现有函数异步,并在执行完后添加一些操作,而不添加任何新函数。似乎下面的解决方案有效。

class Program
{
    static void Main(string[] args)
    {
        ((Action)(async () =>
        {
            await Task.Run(() => LongOperation());
            Console.WriteLine("然后回调已触发");
        }))();
        Console.WriteLine("主线程先完成。");
        Console.ReadKey();
    }
    static void LongOperation()
    {
        Thread.Sleep(3000);
        Console.WriteLine("工作已完成");
    }
}

0
0 Comments

在C#中,我们可以使用异步/等待(async/await)来处理异步操作。然而,有时我们可能需要在代码中内联使用async/await,即在代码的同一行中使用它们。下面是一个例子:

static void Main(string[] args)
{
    Console.WriteLine(v);
    LongOperationAsync().GetAwaiter().GetResult();
    Console.WriteLine("Main thread finished.");
    Console.ReadKey();     
}

在这个例子中,我们在`LongOperationAsync()`方法调用前使用了`.GetAwaiter().GetResult()`来等待异步操作完成。这样做的原因可能是在某些情况下,我们希望以同步的方式执行异步操作,或者我们希望在没有使用async/await的上下文中使用异步操作。

这种方法的一个潜在问题是可能会导致死锁。如果在主线程上使用`.GetAwaiter().GetResult()`来等待异步操作的完成,并且异步操作需要访问主线程上的资源,那么可能会出现死锁情况。

为了解决这个问题,我们可以使用`ConfigureAwait(false)`来告诉异步操作在不需要访问主线程上的资源时不要返回到主线程。这样可以避免死锁的发生。

下面是一个使用`ConfigureAwait(false)`的例子:

static void Main(string[] args)
{
    Console.WriteLine(v);
    LongOperationAsync().ConfigureAwait(false).GetAwaiter().GetResult();
    Console.WriteLine("Main thread finished.");
    Console.ReadKey();     
}

使用`ConfigureAwait(false)`可以提高代码的性能,因为它避免了不必要的线程切换。

通过上面的例子,我们可以看到在C#中可以内联使用async/await,但要注意潜在的死锁问题,并使用`ConfigureAwait(false)`来避免死锁。

0