如果使用 ConfigureAwait(false),async/await 还会死锁吗?
Can async/await still deadlock if ConfigureAwait(false) is used?
根据 this link 在特定情况下 async/await 可能会发生死锁。
但是,如果我一直使用ConfigureAwait(false)
,是否还会出现死锁?
例如:task.ConfigureAwait(false).GetAwaiter().GetResult()
而不是:task.GetAwaiter().GetResult()
是的,它仍然会死锁,ConfigureAwait(false)
必须在所有嵌套等待中实现,其中一些您可能无法控制。
最好的办法是不依赖它,只是不要混合同步和async
调用,让Async/Await传播。
确保它不会死锁(没有await
)的唯一可靠方法(并且有争议)是 offload / Wrap 它到另一个任务和 Wait
那,或者在没有 SynchronizationContext
的框架中
如果要完成的任何事情 task
或任何进一步的嵌套操作已捕获您当前的上下文,如果该上下文绑定到特定线程,它仍然可能死锁 - 因为您正在调用 GetResult
使用该线程 并阻塞,使其无法供其他人使用。
只需使用await
。 await
可以释放 你当前的上下文。
顾名思义,ConfigureAwait()
只影响一个异步的await
。它对 Task.Wait()
、Task.Result
和 Task.GetAwaiter().GetResult()
.
等同步等待没有影响
ConfigureAwait(false)
大致意思是 "I don't care what thread the code after this async await will be resumed on",因此如果原始线程(更准确地说 SynchronizationContext
)被某些东西阻塞,它仍会在不同的线程上继续。但是像 GetAwaiter().GetResult()
这样的同步等待永远不会切换线程。
根据 this link 在特定情况下 async/await 可能会发生死锁。
但是,如果我一直使用ConfigureAwait(false)
,是否还会出现死锁?
例如:task.ConfigureAwait(false).GetAwaiter().GetResult()
而不是:task.GetAwaiter().GetResult()
是的,它仍然会死锁,ConfigureAwait(false)
必须在所有嵌套等待中实现,其中一些您可能无法控制。
最好的办法是不依赖它,只是不要混合同步和async
调用,让Async/Await传播。
确保它不会死锁(没有await
)的唯一可靠方法(并且有争议)是 offload / Wrap 它到另一个任务和 Wait
那,或者在没有 SynchronizationContext
如果要完成的任何事情 task
或任何进一步的嵌套操作已捕获您当前的上下文,如果该上下文绑定到特定线程,它仍然可能死锁 - 因为您正在调用 GetResult
使用该线程 并阻塞,使其无法供其他人使用。
只需使用await
。 await
可以释放 你当前的上下文。
顾名思义,ConfigureAwait()
只影响一个异步的await
。它对 Task.Wait()
、Task.Result
和 Task.GetAwaiter().GetResult()
.
ConfigureAwait(false)
大致意思是 "I don't care what thread the code after this async await will be resumed on",因此如果原始线程(更准确地说 SynchronizationContext
)被某些东西阻塞,它仍会在不同的线程上继续。但是像 GetAwaiter().GetResult()
这样的同步等待永远不会切换线程。