任务继续与async / await并行执行

时间:2013-01-22 16:45:40

标签: c# multithreading task-parallel-library threadpool async-await

在使用 async / await 构造的控制台应用程序的上下文中,我想知道“continuation”是否可以在多个并行运行不同CPU上的线程。

我认为就是这种情况,因为在默认任务调度程序(控制台应用程序中没有SynchronizationContext)上发布了延续,这是线程池。

我知道async / await构造不会构造任何其他线程。仍然应该由线程池为每个CPU构建至少一个线程,因此如果在线程池上发布了continuation,它可以在不同的CPU上并行调度任务延续...这就是我的想法,但出于某种原因我昨天我对此感到困惑,我不再那么确定了。

以下是一些简单的代码:

public class AsyncTest
{
  int i;

  public async Task DoOpAsync()
  {
    await SomeOperationAsync();

    // Does the following code continuation can run 
    // in parrallel ?
    i++;       

    // some other continuation code ....
  }

  public void Start()
  {
    for (int i=0; i<1000; i++)
    { var _ = DoOpAsync(); } // dummy variable to bypass warning
  }
}

SomeOperationAsync 本身并不创建任何线程,让我们假设为了示例它只是依赖于I / O完成端口异步发送一些请求,因此根本不会阻塞任何线程。

现在,如果我调用启动方法将发出1000个异步操作,是否可以在不同的CPU线程上并行运行async方法的延续代码(在等待之后)?即在这种情况下我需要处理线程同步并同步访问字段“i”?

2 个答案:

答案 0 :(得分:6)

是的,您应该将线程同步逻辑放在i++附近,因为多个线程可能会在await之后同时执行代码。

作为for循环的结果,将创建任务数。这些任务将在不同的线程池线程上执行。一旦完成这些任务,将继续执行连续,即等待之后的代码,将在不同的线程池线程上再次执行。这使得多个线程可以同时执行i ++

答案 1 :(得分:5)

您的理解是正确的:在控制台应用程序中,默认情况下,由于默认SynchronizationContext,将继续将延迟计划到线程池。

每个async方法都会同步启动,因此您的for循环将在同一个线程上执行DoOpAsync的开头。假设SomeOperationAsync返回不完整的Task,将在线程池上安排延续。

因此DoOpAsync的每个调用都可以并行继续。