将异步/等待与结果混合

编程入门 行业动态 更新时间:2024-10-07 22:30:26
本文介绍了将异步/等待与结果混合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

让我以几句话开头这个问题:

Let me just preface this question with a few things:

  • 我已经阅读了几个SO问题,要求您不执行此操作(例如如何安全地混合使用同步代码和异步代码)
  • 我已阅读异步/等待-异步编程的最佳做法再次说你不应该这样做
  • I've read several SO questions saying that you should not do this (such as How to safely mix sync and async code)
  • I've read Async/Await - Best Practices in Asynchronous Programming again saying you shouldn't do this
  • 因此,我确实知道这不是最佳做法,也不需要任何人告诉我.这更多是为什么要这样做"的问题.

    So I do know that this is not a best practice, and don't need anyone telling me such. This is more of a "why does this work" question.

    顺带一提,这是我的问题:

    With that out of the way, here is my question:

    我编写了一个小型的GUI应用程序,其中包含2个按钮和一个状态标签.其中一个按钮将在100%的时间内通过同步和异步来再现死锁问题.另一个按钮调用相同的异步方法,但它包装在一个Task中,该方法有效.我知道这不是一个好的编码习惯,但是我想了解为什么,它没有相同的死锁问题.这是代码:

    I've written a small GUI application that has 2 buttons and a status label. One of the buttons will reproduce the deadlock issue with sync and async 100% of the time. The other button calls the same async method but it is wrapped in a Task, this one works. I know this is not a good coding practice, but I want to understand why it doesn't have the same deadlock issue. Here is the code:

    public partial class Form1 : Form { public Form1() { InitializeComponent(); } private async Task<string> DelayAsync() { await Task.Delay(1000); return "Done"; } private void buttonDeadlock_Click(object sender, EventArgs e) { labelStatus.Text = "Status: Running"; // causes a deadlock because of mixing sync and async code var result = DelayAsync().Result; // never gets here labelStatus.Text = "Status: " + result; } private void buttonWorking_Click(object sender, EventArgs e) { labelStatus.Text = "Status: Running"; string result = null; // still technically mixes sync and async, but works, why? result = Task.Run(async () => { return await DelayAsync(); }).Result; labelStatus.Text = "Status: " + result; } }

    推荐答案

    它之所以有效,是因为buttonWorking_Click异步代码(DelayAsync以及传递给Task.Run的async lambda)没有当前的SynchronizationContext,而buttonDeadlock_Click异步代码(DelayAsync)可以.您可以通过在调试器中运行并观看SynchronizationContext.Current来观察差异.

    It works because the buttonWorking_Click async code (DelayAsync as well as the async lambda passed to Task.Run) does not have a current SynchronizationContext, whereas the buttonDeadlock_Click async code (DelayAsync) does. You can observe the difference by running in the debugger and watching SynchronizationContext.Current.

    我会在我的博客文章不要解释死锁情况背后的细节阻止异步代码.

    更多推荐

    将异步/等待与结果混合

    本文发布于:2023-11-26 10:24:33,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1633687.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!