Task.WaitAll方法和 Parallel.Invoke方法的比较

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (68)

我有示例代码来比较并行方法和任务方法的处理时间。这个实验的目标是理解它们是如何工作的。

所以我的问题是:

  1. 为什么并行工作更快然后任务?
  2. 我的结果是否意味着我应该使用Parallel而不是Task?
  3. 我应该在哪里使用任务,并在哪里并行?
  4. 与Parallel相比,使用Task有什么好处?
  5. Task是否只是ThreadPool.QueueUserWorkItem方法的一个包装? public Task SomeLongOperation() { return Task.Delay(3000); } static void Main(string[] args) { Program p = new Program(); List<Task> tasks = new List<Task>(); tasks.Add(Task.Factory.StartNew(() => p.SomeLongOperation())); tasks.Add(Task.Factory.StartNew(() => p.SomeLongOperation())); var arr = tasks.ToArray(); Stopwatch sw = Stopwatch.StartNew(); Task.WaitAll(arr); Console.WriteLine("Task wait all results: " + sw.Elapsed); sw.Stop(); sw = Stopwatch.StartNew(); Parallel.Invoke(() => p.SomeLongOperation(), () => p.SomeLongOperation()); Console.WriteLine("Parallel invoke results: " + sw.Elapsed); sw.Stop(); Console.ReadKey(); }

以下是我的处理结果:

编辑:

更改后的代码如下所示:

    Program p = new Program();
    Task[] tasks = new Task[2];

    Stopwatch sw = Stopwatch.StartNew();
    tasks[0] = Task.Factory.StartNew(() => p.SomeLongOperation());
    tasks[1] = Task.Factory.StartNew(() => p.SomeLongOperation());

    Task.WaitAll(tasks);
    Console.WriteLine("Task wait all results: " + sw.Elapsed);
    sw.Stop();

    sw = Stopwatch.StartNew();
    Parallel.Invoke(() => p.SomeLongOperation(), () => p.SomeLongOperation());
    Console.WriteLine("Parallel invoke results: " + sw.Elapsed);
    sw.Stop();

我的新结果:

编辑2: 当我用Parallel.Invoke替换第一个代码并将Task.WaitAll替换为第二个时,情况已经发生了重大变化。现在并行速度较慢。这让我想起了我的估计错误。我将代码更改为如下所示:

Program p = new Program();
Task[] tasks = new Task[2];

Stopwatch sw = null;
for (int i = 0; i < 10; i++)
{
    sw = Stopwatch.StartNew();
    Parallel.Invoke(() => p.SomeLongOperation(), () => p.SomeLongOperation());
    string res = sw.Elapsed.ToString();
    Console.WriteLine("Parallel invoke results: " + res);
    sw.Stop();
}

for (int i = 0; i < 10; i++)
{
    sw = Stopwatch.StartNew();
    tasks[0] = Task.Factory.StartNew(() => p.SomeLongOperation());
    tasks[1] = Task.Factory.StartNew(() => p.SomeLongOperation());
    Task.WaitAll(tasks);
    string res2 = sw.Elapsed.ToString();
    Console.WriteLine("Task wait all results: " + res2);
    sw.Stop();
}

这里是我的新结果:

现在我可以建议这个实验更加清晰。结果几乎相同。有时并行,有时候任务更快。现在我的问题是:

1.我应该在哪里使用Task并且在哪里并行?

2.与Parallel相比,使用Task有什么好处?

3. Task是否只是ThreadPool.QueueUserWorkItem方法的一个包装?

提问于
用户回答回答于

编辑从本文MSDN

Parallel和Task都是ThreadPool的包装器。并行调用也等待,直到所有任务完成。

与您的问题相关:

使用Task,Parallel或ThreadPool取决于执行并行任务所需的控制粒度。我个人习惯了Task.Factory.StartNew(),但这是个人意见。同样涉及到ThreadPool.QueueUserWorkItem()

用户回答回答于

如果你启动非通用任务并立即Wait为他们使用Parallel.Invoke

使用任务如果:

  • 你不要马上等待
  • 你需要返回值
  • 你需要给所调用的方法提供参数
  • 你需要TaskCreationOptions功能
  • 你需要CancellationTokenTaskScheduler功能,而不想使用ParallelOptions

是的,你可以解决其中的一些问题,例如,Parallel.Invoke(() => p.OpWithToken(CancellationToken)但是混淆你的意图。Parallel.Invoke是为了使用尽可能多的CPU功能来完成一大堆工作。它完成了,它不会陷入僵局,你事先知道这一点。

所属标签

可能回答问题的人

  • HKC

    红客学院 · 创始人 (已认证)

    26 粉丝7 提问5 回答
  • Dingda

    Dingda · 站长 (已认证)

    4 粉丝0 提问3 回答
  • 西风

    renzha.net · 站长 (已认证)

    9 粉丝1 提问3 回答
  • 螃蟹居

    1 粉丝0 提问2 回答

扫码关注云+社区

领取腾讯云代金券