我发现了一些使用c#async
/ await
keywords的异步编程的最佳实践(我是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();
}
Run Code Online (Sandbox Code Playgroud)
如果我自己尝试剖析它,主线程会产生一个新线程MyWebService.GetDataAsync();
,但由于主线程在那里等待,它等待结果GetDataAsync().Result
.同时,说数据准备好了.为什么主线程不继续它的延续逻辑并从中返回字符串结果GetDataAsync()
?
有人可以解释一下为什么上面的例子中存在死锁吗?我完全不知道问题是什么......