我正在使用 .ConfigureAwait(false)
调用异步库方法,但仍然遇到了死锁问题。 (我在ASP.NET控制器API中使用它)
但是,如果我将相同的方法包装在 Task.Run()
中,它就可以正常工作。
我的理解是,如果库方法内部没有使用 ConfigureAwait
,那么添加 ConfigureAwait
不会解决问题,因为在库调用中它会导致死锁(我们通过使用 .Result
阻塞它)。但是,如果是这种情况,为什么 Task.Run()
可以正常工作呢?虽然它将无法在相同的上下文/线程中继续执行。
这篇文章有讲述到。顺便说一句,我已经阅读过不少Stephen Cleary的文章,但为什么Task.Run()能够正常工作还是个谜。
代码片段:
// This Create Method results in Deadlock
public async Task<string> Create(MyConfig config)
{
Document doc = await Client.CreateDocumentAsync(CollectionUri, config).ConfigureAwait(false);
return doc.Id;
}
// Uses Task.Run() which works properly, why??
public string Create(MyConfig config)
{
Document doc = Task.Run(() => Client.CreateDocumentAsync(CollectionUri, config)).Result;
return doc.Id;
}
[HttpPost]
public ActionResult CreateConfig(MyConfig config)
{
string id = Create(config).Result;
return Json(id);
}
await [async call].ConfigureAwait(false)
或者await Task.Run(async ()=> await [async call]).ConfigureAwait(false)
。 - Thanasis IoannidisConfigureAwait(false)
通常是一个错误。因此文档可能会出错。 - Stephen Cleary