请注意在 UI 线程上执行工作的指南,收集在我的博客上:
- 一次阻塞 UI 线程的时间不要超过 50 毫秒。
- 您可以每秒在 UI 线程上安排约 100 个延续; 1000 太多了。
您应该使用两种技术:
1) Use ConfigureAwait(false)
当你可以的时候。
E.g., await MyAsync().ConfigureAwait(false);
代替await MyAsync();
.
ConfigureAwait(false)
告诉await
您不需要在当前上下文上恢复(在本例中,“在当前上下文上”意味着“在 UI 线程上”)。然而,对于其余的async
方法(之后ConfigureAwait
),您无法执行任何假设您处于当前上下文中的操作(例如,更新 UI 元素)。
有关详细信息,请参阅我的 MSDN 文章异步编程的最佳实践.
2) Use Task.Run
调用 CPU 密集型方法。
你应该使用Task.Run
,但不在您希望可重用的任何代码(即库代码)中。所以你用Task.Run
to call该方法,而不是作为执行该方法的。
因此纯粹受 CPU 限制的工作将如下所示:
// Documentation: This method is CPU-bound.
void DoWork();
你会用它来称呼Task.Run
:
await Task.Run(() => DoWork());
方法是mixtureCPU 限制和 I/O 限制的应该有一个Async
带有指出其 CPU 限制性质的文档的签名:
// Documentation: This method is CPU-bound.
Task DoWorkAsync();
您也可以使用它来调用Task.Run
(因为它部分受 CPU 限制):
await Task.Run(() => DoWorkAsync());