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

叶尔达·库曼加利耶夫(Yeldar Kurmangaliyev)

我在乔恩·斯凯特(Jon Skeet)的“ C#深入。第三版”中找到了以下示例:

static async Task<int> GetPageLengthAsync(string url)
{
    using (HttpClient client = new HttpClient())
    {
        Task<string> fetchTextTask = client.GetStringAsync(url);
        int length = (await fetchTextTask).Length;
        return length;
    }
}

public static void Main()
{
    Task<int> lengthTask = GetPageLengthAsync("http://csharpindepth.com");
    Console.WriteLine(lengthTask.Result);
}

我希望这段代码会死锁,但不会死锁。

如我所见,它是这样工作的:

  1. Main方法GetPageLengthAsync在主线程中同步调用
  2. GetPageLengthAsync使一个异步请求,并立即返回Task<int>Main说“等一会儿,我会回到你的第二个int类型”。
  3. Main继续执行并偶然发现lengthTask.Result导致主线程阻塞并等待lengthTask完成其工作。
  4. GetStringAsync完成并等待主线程变得可用以执行Length并开始继续。

但似乎我误会了一些东西。为什么此代码不会死锁?

关于等待/异步死锁的这个StackOverflow问题中的代码似乎执行相同的操作,但是死锁。

帕纳吉奥提斯·卡纳沃斯(Panagiotis Kanavos)

await 返回原始同步上下文,无论是UI线程(在桌面UI应用程序中)还是ASP.NET(不是核心)中的请求上下文。

在GUI应用程序中,您会遇到死锁,因为UI线程被锁定了.Resultawait将永远等待这个电话结束。

控制台应用程序和ASP.NET Core没有同步上下文,因此调用.Result不会导致死锁。

VS 15.3的PS:

Visual Studio 2017 15.3预览版2(gasp)允许异步主应用程序。有了它,您可以编写:

public static Task Main()
{
    var length = await GetPageLengthAsync("http://csharpindepth.com");
    Console.WriteLine(length);
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么此控制台应用程序中的异步等待模式会导致死锁?

异步等待导致死锁

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

导致死锁的异步/等待示例

为什么在Windows Service中阻止异步会导致死锁?

此代码不应该导致死锁吗?

此“同步”代码会导致死锁吗?

为什么在使用默认的prepare_arch_switch()时schedule()不会导致死锁

为什么WPF的Dispatcher.Invoke在主线程上运行时不会导致死锁?

Erlang/Akka 等如何在后台发送消息?为什么不会导致死锁?

为什么移动此行会导致死锁?

为什么pthread_cond_signal导致死锁

Java等待并通知会导致死锁

为什么代码不总是导致死锁,而是试图了解可重入锁与同步块的工作原理?

for循环导致死锁

为什么在静态初始化程序中使用lambda进行并行流会导致死锁?

为什么以不同顺序解锁两个锁定的银行帐户会导致死锁?

为什么在Golang中发送大于缓冲通道大小的值会导致死锁错误?

为什么在同一goroutine中使用未缓冲的通道会导致死锁?

Java:为什么当锁为null时这会导致死锁?

为什么重新使用条件变量的互斥锁会导致死锁?

任务异步调用不返回会导致死锁

为什么此JavaScript异步/等待代码无法按预期运行?

为什么此代码不能用作死锁?

为什么从Actix Web处理程序内的Rusoto S3流中读取会导致死锁?

使用单线程执行器时,为什么“ header.get()+ footer.get()”会导致死锁?

为什么此代码使用异步方法?

为什么此代码导致StackOverflow错误:

为什么此instanceof代码可以正常工作并且不会导致编译时错误?