【译】ConfigureAwait FAQ
内容提要
本文介绍了.NET中的async/await和ConfigureAwait方法,以及与之相关的SynchronizationContext和TaskScheduler。使用ConfigureAwait(false)可以避免死锁和提高性能,但不能保证回调不会在原始上下文中运行。在某些情况下,可以只在方法中第一个await处使用。使用Task.Run也可以避免使用ConfigureAwait(false)。本文还回答了一些关于ConfigureAwait的常见问题。
关键要点
-
.NET 中的 async/await 和 ConfigureAwait 方法的引入及其重要性。
-
SynchronizationContext 提供了在不同同步模型中传播同步上下文的功能。
-
SynchronizationContext 的派生类如 WindowsFormsSynchronizationContext 和 DispatcherSynchronizationContext 允许在 UI 线程上执行委托。
-
TaskScheduler 是与 Task 相关联的调度程序,提供了任务的调度和执行机制。
-
async/await 与 SynchronizationContext 和 TaskScheduler 的关系,确保 UI 线程安全地更新控件。
-
ConfigureAwait(false) 的作用是避免在原始上下文中强制调用回调,从而提高性能和避免死锁。
-
在应用程序级代码中,通常应使用默认的 ConfigureAwait(true);而在通用库代码中,推荐使用 ConfigureAwait(false)。
-
ConfigureAwait(false) 不保证后续代码不会在原始上下文中运行。
-
ConfigureAwait(false) 应该在每个 await 调用中使用,而不是仅在第一个 await 处使用。
-
Task.Run 可以避免使用 ConfigureAwait(false),因为它在线程池线程上执行。
-
使用 SynchronizationContext.SetSynchronizationContext 可能无法有效避免使用 ConfigureAwait(false)。
-
GetAwaiter().GetResult() 不需要使用 ConfigureAwait(false)。
-
在特定环境中,可能不需要使用 ConfigureAwait(false),但需谨慎判断。
-
ASP.NET Core 中的 SynchronizationContext 行为与 ASP.NET 不同,减少了使用 ConfigureAwait(false) 的需要。
-
IAsyncEnumerable 和 IAsyncDisposable 支持 ConfigureAwait 的使用。
-
AsyncLocal 数据流与 ExecutionContext 相关,与 SynchronizationContext 分开,ConfigureAwait 不影响其流动。
-
当前没有内置的语言特性来自动处理 ConfigureAwait(false) 的需求。