TaskCompletionSource执行缓慢

时间:2019-01-24 07:18:28

标签: c# .net taskcompletionsource

通过在同步方法中遍历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:");
});

1 个答案:

答案 0 :(得分:1)

您对Parallel.For()有误解。

首先,Parallel.For()不是为异步任务设计的。在许多帖子中已经提到过:

想象一下,在厨房里,您有5个厨师(线程),Parallel.For()正在将每个待处理的菜肴逐一分配给每个厨师。但是async-await正在分配“有前途的承诺,我会做一道菜”来做饭,这是一个约会,只有线程启动它并“完成”该过程。

这就是为什么您在async-await示例中获得非常快速的响应的原因。但是这一行:

System.Console.WriteLine("ended:");

未打印。当工作线程遇到await时,此任务结束。


让我们简化您使用的示例,TaskCompletionSource不是测试async-awaitParallel.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);
});

并行是怎么回事,是的,它很慢,启动线程和任务计划程序要花钱。但这实际上是在告诉您任务在程序结束之前已经完成。