为什么此异步/等待代码不会死锁

时间:2019-01-31 23:29:03

标签: c# async-await

我正在阅读this中有关死锁的文章,并且尝试使用自己的代码,但没有死锁问题。为什么会这样?

我期望:

  1. GetJsonAsync完成等待,即将返回jsonString

  2. Main正在执行jsonTask.Result并保留上下文

  3. GetJsonAsync要返回jsonString直到上下文可用

  4. 将发生僵局

        public static void Main(string[] args)
        {
            var jsonTask = GetJsonAsync();
            int i = jsonTask.Result;
            Console.WriteLine(jsonTask.Result);
        }
    
        public static async Task<int> GetJsonAsync()
        {
            var jsonString = await ReturnIntAsync();
            return jsonString;
        }
    
        public static async Task<int> ReturnIntAsync()
        {
            int i = 0;
            await Task.Run(() => i++);
            return i;
        }
    

1 个答案:

答案 0 :(得分:3)

它不会死锁,因为没有同步SynchronizationContext,因此async方法恢复在线程池线程而不是主线程上执行。

文章中的相关引号(添加了重点):

  

在这种情况下:请记住,在我的介绍性帖子中,等待任务后,方法继续执行时,它将在上下文中继续执行。

     

在第一种情况下,此上下文是UI上下文(适用于任何除控制台应用程序之外的UI)。在第二种情况下,此上下文是ASP.NET请求上下文...

     

对于UI示例,“上下文”是UI上下文;对于ASP.NET示例,“上下文”是ASP.NET请求上下文。这种死锁可能是由于“上下文”引起的。

如果您真的想以此方式使控制台应用程序死锁,则可以使用AsyncContext from my AsyncEx library在控制台应用程序的主线程上安装单线程上下文。