gpt4 book ai didi

c# - 将异步/等待与结果混合

转载 作者:太空狗 更新时间:2023-10-29 17:33:57 25 4
gpt4 key购买 nike

让我用几件事作为这个问题的序言:

  1. 我读过几个 SO 问题说你不应该这样做(例如 How to safely mix sync and async code)
  2. 我读过 Async/Await - Best Practices in Asynchronous Programming再次说你不应该这样做

所以我知道这不是最佳实践,不需要任何人告诉我这样的事情。这更像是一个“为什么这样做”的问题。

顺便说一句,这是我的问题:

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

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.Runasync lambda >) 没有当前的 SynchronizationContext,而 buttonDeadlock_Click 异步代码 (DelayAsync) 有。您可以通过在调试器中运行并观察 SynchronizationContext.Current 来观察差异。

我在我的博文 Don't Block on Async Code 中解释了死锁场景背后的细节.

关于c# - 将异步/等待与结果混合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38642798/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com