gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-29 03:38:26 26 4
gpt4 key购买 nike

我发现了一些使用 c# 的 async/await 关键字进行异步编程的最佳实践(我是 c# 5.0 的新手)。

给出的建议之一如下:

稳定性:了解您的同步上下文

...一些同步上下文是不可重入的和单线程的。这意味着在给定时间只能在上下文中执行一个工作单元。 Windows UI 线程或 ASP.NET 请求上下文就是一个例子。在这些单线程同步上下文中,很容易让自己陷入死锁。如果您从单线程上下文中生成任务,然后在上下文中等待该任务,您等待的代码可能会阻塞后台任务。

public ActionResult ActionAsync()
{
// DEADLOCK: this blocks on the async task
var data = GetDataAsync().Result;

return View(data);
}

private async Task<string> GetDataAsync()
{
// a very simple async method
var result = await MyWebService.GetDataAsync();
return result.ToString();
}

如果我尝试自己剖析它,主线程会在 MyWebService.GetDataAsync(); 中生成一个新线程,但由于主线程在那里等待,它会等待 中的结果>GetDataAsync().Result。同时,说数据准备好了。为什么主线程不继续它的延续逻辑并从 GetDataAsync() 返回字符串结果?

谁能解释一下为什么上面的例子会出现死锁?我完全不知道问题是什么......

最佳答案

看看this example , Stephen 给你一个明确的答案:

So this is what happens, starting with the top-level method (Button1_Click for UI / MyController.Get for ASP.NET):

  1. The top-level method calls GetJsonAsync (within the UI/ASP.NET context).

  2. GetJsonAsync starts the REST request by calling HttpClient.GetStringAsync (still within the context).

  3. GetStringAsync returns an uncompleted Task, indicating the REST request is not complete.

  4. GetJsonAsync awaits the Task returned by GetStringAsync. The context is captured and will be used to continue running the GetJsonAsync method later. GetJsonAsync returns an uncompleted Task, indicating that the GetJsonAsync method is not complete.

  5. The top-level method synchronously blocks on the Task returned by GetJsonAsync. This blocks the context thread.

  6. ... Eventually, the REST request will complete. This completes the Task that was returned by GetStringAsync.

  7. The continuation for GetJsonAsync is now ready to run, and it waits for the context to be available so it can execute in the context.

  8. Deadlock. The top-level method is blocking the context thread, waiting for GetJsonAsync to complete, and GetJsonAsync is waiting for the context to be free so it can complete. For the UI example, the "context" is the UI context; for the ASP.NET example, the "context" is the ASP.NET request context. This type of deadlock can be caused for either "context".

您应该阅读的另一个链接:Await, and UI, and deadlocks! Oh my!

关于c# - 导致死锁的异步/等待示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15021304/

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