且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-02-03 19:13:00

查看 这个例子,Stephen 给你一个明确的答案:

Take a look at this example, Stephen has a clear answer for you:

这就是发生的事情,从***方法开始(Button1_Click 用于 UI/MyController.Get 用于 ASP.NET):

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

  1. ***方法调用 GetJsonAsync(在 UI/ASP.NET 上下文中).

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

GetJsonAsync 通过调用 HttpClient.GetStringAsync(仍在上下文中)启动 REST 请求.

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

GetStringAsync 返回未完成的Task,表示REST请求未完成.

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

GetJsonAsync 等待 GetStringAsync 返回的 Task.上下文被捕获,稍后将用于继续运行 GetJsonAsync 方法.GetJsonAsync返回一个未完成的Task,说明GetJsonAsync方法没有完成.

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.

***方法同步阻塞 GetJsonAsync 返回的 Task.这会阻塞上下文线程.

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

... 最终,REST 请求将完成.这完成了 GetStringAsync 返回的 Task.

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

GetJsonAsync 的延续现在可以运行了,它会等待上下文可用,以便在上下文中执行.

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.

死锁.顶层方法正在阻塞上下文线程,等待 GetJsonAsync 完成,而 GetJsonAsync 正在等待上下文空闲以便它可以完成.对于 UI 示例,上下文"是 UI 上下文;对于 ASP.NET 示例,上下文"是 ASP.NET 请求上下文.任何一种上下文"都可能导致这种类型的死锁.

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".

您应该阅读的另一个链接:等待、UI 和死锁!哦,天哪!

Another link you should read: Await, and UI, and deadlocks! Oh my!