dar*_*key 7 c# multithreading threadpool task-parallel-library 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
}
}
Run Code Online (Sandbox Code Playgroud)
SomeOperationAsync本身不会创建任何线程,让我们假设为了示例它只是依赖I/O完成端口异步发送一些请求,因此根本不会阻塞任何线程.
现在,如果我调用将发出1000个异步操作的Start方法,是否可以在不同的CPU线程上并行运行async方法的延续代码(在await之后)?即在这种情况下我是否需要处理线程同步并同步对字段"i"的访问?
是的,您应该放置线程同步逻辑,i++因为多个线程可能await在同一时间执行代码.
作为for循环的结果,将创建任务数.这些任务将在不同的线程池线程上执行.一旦完成这些任务,将继续执行继续,即等待之后的代码,将在不同的线程池线程上再次执行.这使得多个线程可以同时执行i ++
您的理解是正确的:在控制台应用程序中,默认情况下,由于默认值,将继续安排到线程池SynchronizationContext。
每个async方法的确同步启动,因此您的for循环将DoOpAsync在同一线程上执行的开头。假设SomeOperationAsync返回的不完整Task,继续将在线程池中进行安排。
因此,的每个调用DoOpAsync可以并行进行。