无法在异步等待中复制死锁

Sea*_*ean 5 .net c# deadlock task-parallel-library async-await

我希望在下面的代码上发生死锁:

static async Task<int> DelayAndReturnAsync(int val)
{
    await Task.Delay(TimeSpan.FromSeconds(val));
    return val;
}

static async Task<int> ProcessTaskAsync()
{
    var taskA = await DelayAndReturnAsync(3);
    int num = taskA++;
    return num;
}

static void Main(string[] arg)
{
    var testTask = ProcessTaskAsync();
    testTask.Wait();
    Console.WriteLine("Done");
}
Run Code Online (Sandbox Code Playgroud)

由于主线程(当前上下文)在调用ProcessTaskAsync()和被阻塞之后处于等待状态teskTask.Wait(),因此它无法返回到该方法并在DelayAndReturnAsync()完成时继续其余代码.主线程将等待它等待ProcessTaskAsync完成ProcessTaskAsync(原始上下文)继续其余的代码.因此陷入僵局.

如果我的理解有任何问题,请告诉我.我原本试图复制死锁并测试使用ConfigureAwait(false)方法的解决方案ProcessTaskAsync.例如ProcessTaslAsync.ConfigureAwait(false).

i3a*_*non 6

该死锁只能SynchronizationContext在控制台应用程序中默认存在的情况下发生.因为没有SynchronizationContext开始它就好像每个await隐含地添加ConfigureAwait(false).

您可以在UI或asp.net应用程序中尝试它,或者甚至更好地添加SynchronizationContextStephen Cleary的AsyncContext测试中:

"该AsyncContext类型提供了执行异步操作的上下文.await关键字需要返回一个上下文;对于大多数程序,这是一个UI上下文,您不必担心它.ASP.NET也提供了一个适当的上下文,你不必使用自己的.

但是,控制台应用程序和Win32服务没有合适的上下文,AsyncContext或者AsyncContextThread可以在这些情况下使用."