繁体   English   中英

使用异步/等待任务继续并行执行

[英]Task continuation parallel execution with async/await

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

我认为是这种情况,因为继续发布在默认任务计划程序(控制台应用程序中没有SynchronizationContext)上,即线程池。

我知道async / await构造不会构造任何其他线程。 仍然应该由线程池为每个CPU构造至少一个线程,因此,如果在线程池上发布了延续,它可以在不同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次异步操作的Start方法,异步方法的继续代码(在等待之后)是否可以在不同的CPU线程上并行运行? 也就是说,在这种情况下,我是否需要注意线程同步并同步对字段“ i”的访问?

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

由于for循环,将创建许多任务。 这些任务将在不同的线程池线程上执行。 这些任务完成后,继续(即等待后的代码)将在不同的线程池线程上再次执行。 这使得多个线程可以同时执行i ++

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

每个async方法的确会同步启动,因此您的for循环将在同一线程上执行DoOpAsync的开头。 假设SomeOperationAsync返回一个不完整的Task ,则继续将在线程池中进行调度。

因此, DoOpAsync每个调用DoOpAsync可以并行进行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM