首页 > 解决方案 > 为什么这个 async/await 代码不会死锁

问题描述

我正在阅读这篇关于死锁的文章,我尝试使用自己的代码,但它没有死锁问题。这是为什么?

我期待:

  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;
        }
    

标签: c#async-await

解决方案


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

文章中的相关引用(强调添加):

情况如下:从我的介绍文章中记住,在等待任务之后,当方法继续时,它将在上下文中继续。

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

对于 UI 示例,“上下文”是 UI 上下文;对于 ASP.NET 示例,“上下文”是 ASP.NET 请求上下文。任何一种“上下文”都可能导致这种类型的死锁。

如果你真的想以这种方式死锁一个控制台应用程序,你可以使用AsyncContext 我的AsyncEx在你的控制台应用程序的主线程上安装一个单线程上下文。


推荐阅读