让我们假设我有这个代码:
await Task1Async().ConfigureAwait(false);
await Task2ASync().ConfigureAwait(false);
配置等待允许在与调用线程不同的线程上运行。
但是,如果我执行以下操作:
Task.WaitAll(
Task1Async,
Task2Async
);
我理解的一些解释。
如果你这样做:
//some code
await Task1Async();
await Task2ASync();
//some other code
它会像这样执行:
如果您改为这样做:
//some code
await Task1Async().ConfigureAwait(false);
await Task2ASync().ConfigureAwait(false);
//some other code
这是发生的事情:
1. 调用线程执行“一些代码”。
2.然后异步执行Task1Async(线程池)。
3. 当前线程从函数返回,意味着它没有被阻塞。4. 当 Task1Async 完成时,下一行不是在捕获的上下文上执行,而是使用线程池执行。然后启动 Task2Async。5. Task2Async 完成,然后最后的“一些其他代码”再次运行,而不是在调用线程上,而是使用线程池。
在这两种情况下,函数都按顺序运行,但不会阻塞调用线程。
使用 Task.WaitAll,这两个任务使用线程池顺序运行。即每个任务都在一个单独的线程中启动并等待完成。这里的主要区别是调用线程被阻塞,直到两个任务都完成。
如果你想并行运行这两个任务并且不阻塞调用线程,你可以await WhenAll:
await Task.WhenAll(Task1Async, Task2Async);
最后,如果您在 await 之后有任何想要运行的代码并且不需要在 UI 上下文中运行,那么您将执行以下操作:
await Task.WhenAll(Task1Async, Task2Async).ConfigureAwait(false);
旁注:您想要 ConfigureAwait(true) 或省略它的原因是,例如您有一个按钮单击处理程序并且想要更新需要在 UI 线程上的内容:
public void OnClick(..args..)
{
Button.IsEnabled = false;
await SomeTask();
//must be on UI thread. This code is executed on the context captured by the await above.
Button.IsEnabled = true;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句