【发布时间】:2020-10-22 04:35:28
【问题描述】:
我在各个地方(包括 SO 问题)都阅读过有关 ConfigureAwait 的信息,以下是我的结论:
- ConfigureAwait(true):在运行 await 之前的代码所在的同一线程上运行其余代码。
- ConfigureAwait(false):在运行等待代码的同一线程上运行其余代码。
- 如果 await 后面是访问 UI 的代码,则该任务应附加
.ConfigureAwait(true)。否则,由于另一个线程访问 UI 元素,将发生 InvalidOperationException。
我的问题是:
- 我的结论正确吗?
- ConfigureAwait(false) 何时会提高性能,何时不会?
- 如果为 GUI 应用程序编写,但下一行不访问 UI 元素。我应该使用 ConfigureAwait(false) 还是 ConfigureAwait(true) ?
【问题讨论】:
-
我不建议使用 SO 作为有关 async/await 的主要信息来源。自认为知道它是如何工作的人在这里有很多错误信息。使用 Stephen Toub、Stephen Cleary、Jon Skeet 的文档和著作。但要违背我自己的建议,您可能会找到one of my blog posts helpful。
-
Are my conclusions correct- 没有。异步与线程无关。ConfigureAwait与某个线程的使用没有直接对应关系。参见例如stackoverflow.com/q/46094134/11683. -
您必须定义“性能”的含义。异步代码实际上比相同的非异步代码性能稍差。主要优势在于可扩展性和并行性,尤其是 I/O 绑定代码。
-
@Youssef13 Async 关注的是同步上下文,而不是线程。使用或不使用单独的线程是一个实现细节,除非另有明确说明(例如使用
Task.Run())。ConfigureAwait(false)premits 在不捕获同步上下文的情况下恢复,而不是需要它。对于某些同步上下文(例如,在 Winforms 应用程序中使用的上下文),“在同一上下文中恢复”意味着“在 UI 线程上运行”。对于其他情况,它可能并不意味着,或者可能根本没有明显的影响。 -
@Youssef13 是的,你找到了 Stephen Toub。他谈到了可能不适用于您的“热路径”,性能增益可能太小而无法衡量(只是一个没有看到您的代码的假设)。不要将
ConfigureAwait(false)用于“上下文感知”代码,例如完成后必须在 UI 线程上执行的代码。另一个示例是在 ASP.NET WebForms 应用程序中访问 HttpContext。我发布的链接指向一个探索这些事情的 WPF 应用程序,包括在使用带有草率的库代码的 ConfigureAwait(false) 时如何仍然死锁。
标签: c# .net asynchronous async-await configureawait