[英]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.