传递给 Task.WaitAll() 的任务会在不同的上下文中运行吗?

托马斯

让我们假设我有这个代码:

await Task1Async().ConfigureAwait(false);
await Task2ASync().ConfigureAwait(false);

配置等待允许在与调用线程不同的线程上运行。

但是,如果我执行以下操作:

Task.WaitAll(
    Task1Async,
    Task2Async
);
  • 任务是否在相同的上下文中运行?
  • 如果没有,我可以做一个等效的ConfigureAwait(false)吗?
蒂姆·拉特

我理解的一些解释。

如果你这样做:

//some code

await Task1Async();
await Task2ASync();

//some other code

它会像这样执行:

  1. 调用线程(例如 UI 上下文)同步执行“一些代码”。
  2. 然后它异步启动 Task1Async,这将在 ThreadPool 上下文中发生,(除非它已经完成,在这种情况下,执行在下面的第 4 点同步继续)。如果任务未完成,则在此处捕获调用上下文
  3. 当前线程然后从函数返回,这意味着它没有被阻塞。
  4. 当 Task1Async 完成时,下一行在捕获的上下文中执行,例如 UI 上下文。然后通过线程池上下文异步启动 Task2Async(同样,如果已经完成,则继续同步执行)
  5. Task2Async 完成,然后使用捕获的上下文再次运行最后的“其他一些代码”

如果您改为这样做:

//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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用Task.WaitAll()处理等待的任务?

来自分类Dev

任务等待vs Task.WaitAll

来自分类Dev

任务等待vs Task.WaitAll

来自分类Dev

C#中的Task.WaitAll挂起了任务的执行

来自分类Dev

C#中的Task.WaitAll挂起了任务的执行

来自分类Dev

Task.WaitAll()的默认超时

来自分类Dev

Task.WaitAll is not waiting - Explanation

来自分类Dev

使用Task.Start触发任务时卡在Task.WaitAll(tasks.ToArray())

来自分类Dev

在传递给Task.WhenAll()的任务上使用ConfigureAwait(false)

来自分类Dev

如何通过将脚本路径传递给padrino在padrino上下文中运行脚本

来自分类Dev

处理Task.WaitAll中已取消的任务和任务异常?

来自分类Dev

延续任务上的Task.WaitAll()仅延迟原始任务的执行?

来自分类Dev

I / O绑定任务的Parallel.ForEach比Task.WaitAll快吗?

来自分类Dev

子任务与WaitAll

来自分类Dev

子任务与WaitAll

来自分类Dev

在WCF方法中使用Task.WaitAll

来自分类Dev

Task.WaitAll()无法正常工作

来自分类Dev

C#Task.WaitAll不在等待

来自分类Dev

Task.WaitAll没有在等待-解释

来自分类Dev

Task.WaitAll无限期阻止

来自分类Dev

将“ refetch”传递给上下文

来自分类Dev

“ foreach with task.Wait”和Task.WaitAll之间的区别

来自分类Dev

“ foreach with task.Wait”和Task.WaitAll之间的区别

来自分类Dev

为什么Task.WaitAll不等到我的所有任务都完成后才开始?C#

来自分类Dev

WaitAll之后再次触发任务

来自分类Dev

WaitAll用于更改列表<任务>

来自分类Dev

如何在基于类的视图的上下文中传递给Django中的模板?

来自分类Dev

在哪个上下文中执行被传递给ruby中的方法的块?

来自分类Dev

Why does Task.WaitAll() not block or cause a deadlock here?

Related 相关文章

热门标签

归档