通过在synchronous方法中循环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:");
});发布于 2019-01-24 16:18:48
你对Parallel.For()有一些误解。
首先,Parallel.For()不是为异步任务设计的。它已经在许多帖子中提到过:
想象一下,在一个厨房里,你有5个厨师(线程),Parallel.For()将每个未决的菜一个接一个地分配给每个厨师。但是async-await,正在分配“承诺我会做一道菜”的协议来做饭,这是一个预约,只有线程启动并“完成”这个过程。
这就是为什么在async-await示例中你会得到非常快的响应。但这一行:
System.Console.WriteLine("ended:");未打印。当工作线程遇到await时,此任务结束。
让我们简化一下您正在使用的示例,对于测试async-await和Parallel.For()之间的差异,TaskCompletionSource不是一个很好的示例。
//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 one永远不会打印ended: index。尝试在末尾添加一行Task.Delay(2000).Wait();,您会注意到ended:index终于打印出来了。
尝试在延迟中将1000减少为1,它可能会打印一些ended,但它是 by 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);
});并行怎么样,是的,它是“慢”的,启动线程和任务调度器占用了成本。但它实际上是在告诉你在程序结束之前任务已经完成了。
https://stackoverflow.com/questions/54341237
复制相似问题