通过在同步方法中遍历TaskCompletionSource的多个实例,超过5个程序的执行速度会变慢,但是在异步方法中,您不会遇到此问题。
这是有问题的代码使用同步方法,执行速度变慢,大约在1秒内创建了一个
Parallel.For(1, 100, (index) =>
{
System.Console.WriteLine("start:");
var t = new TaskCompletionSource<string>();
count++;
System.Console.WriteLine("end:" + count + "\n");
t.Task.Wait();
System.Console.WriteLine("ended:");
});
这是没有问题的代码,执行速度非常快
Parallel.For(1, 100, async (index) =>
{
System.Console.WriteLine("start:");
var t = new TaskCompletionSource<string>();
count++;
System.Console.WriteLine("end:" + count + "\n");
await t.Task;
System.Console.WriteLine("ended:");
});
答案 0 :(得分:1)
您对Parallel.For()
有误解。
首先,Parallel.For()
不是为异步任务设计的。在许多帖子中已经提到过:
想象一下,在厨房里,您有5个厨师(线程),Parallel.For()
正在将每个待处理的菜肴逐一分配给每个厨师。但是async-await
正在分配“有前途的承诺,我会做一道菜”来做饭,这是一个约会,只有线程启动它并“完成”该过程。
这就是为什么您在async-await
示例中获得非常快速的响应的原因。但是这一行:
System.Console.WriteLine("ended:");
未打印。当工作线程遇到await
时,此任务结束。
让我们简化您使用的示例,TaskCompletionSource
不是测试async-await
和Parallel.For()
之间差异的好示例。
//Async
Parallel.For(1, 100, async (index) =>
{
System.Console.WriteLine("start:" + index);
await Task.Delay(1000);
System.Console.WriteLine("ended:" + index);
});
//Task.Delay(2000).Wait();
Async-await
在这种情况下将永远不会打印ended: index
。尝试在末尾添加一行Task.Delay(2000).Wait();
,您会发现ended:index
最终被打印出来。
尝试将1000
延迟减少到1
,它可能会打印一些ended
,但是Parallel.for
不能保证,这意味着您的任务根本不会在Parallel.for()
线程中等待,它被async-await
的另一个线程保留。
//Sync
Parallel.For(1, 100, (index) =>
{
System.Console.WriteLine("start:" + index);
Task.Delay(1000).Wait();
System.Console.WriteLine("ended:" + index);
});
并行是怎么回事,是的,它很慢,启动线程和任务计划程序要花钱。但这实际上是在告诉您任务在程序结束之前已经完成。