如果使用ConfigureAwait(false),异步/等待仍然可以死锁吗?

时间:2019-03-06 08:18:07

标签: c# async-await deadlock

根据this link,在特定情况下,异步/等待会导致死锁。

但是,如果我始终使用line 1 \n line 2,还会发生死锁吗?

例如:ConfigureAwait(false)

而不是:task.ConfigureAwait(false).GetAwaiter().GetResult()

3 个答案:

答案 0 :(得分:2)

是的,它仍然可能会死锁,ConfigureAwait(false)将必须在所有嵌套等待中实现,其中有些您可能无法控制。

最好的方法是不要依赖它,只是不要混合同步,不要async调用,而要传播 Async / Await

确保它不会死锁(没有await)的唯一有保证的方法(有争议)是卸载 / 包装Wait,或者在没有 SynchronizationContext

的框架中

答案 1 :(得分:2)

如果要完成的任何操作task或任何其他嵌套操作都捕获了您当前的上下文,如果该上下文绑定到特定线程,它仍然可能死锁-因为您正在调用{{1} } 使用该线程并进行阻止,使其他人无法使用它。

只需使用GetResultawait可以释放您当前的上下文。

答案 2 :(得分:1)

顾名思义,ConfigureAwait()仅影响异步await。它对Task.Wait()Task.ResultTask.GetAwaiter().GetResult()之类的同步等待没有影响。

ConfigureAwait(false)的意思大致是“我不在乎此异步等待后的代码将在哪个线程上恢复”,因此,如果原始线程(更准确地为SynchronizationContext)被某些内容阻塞,它将仍然在另一个线程上继续。但是像GetAwaiter().GetResult()这样的同步等待永远不会切换线程。