异步调用并行for循环

时间:2016-09-02 16:42:07

标签: c# multithreading asynchronous task-parallel-library

我想做这样的事情:

public async Task MyMethod()
{
    // Do some preparation

    await Parallel.ForEachAsync(0, count, i => { // Do some work //});

    // do some finalization
}

然而,我没有找到一种优雅的方式。我想到了两种方法,但它们是次优的:

  1. 我唯一想到的是手动分区范围,创建任务,然后使用Task.WhenAll。
  2. 使用以下代码Task.Factory.StartNew(() => Parallel.For(...));
    问题在于它的浪费"异步任务上的一个线程。
  3. 使用TPL Dataflow的ActionBlock,逐个发布整数。缺点是它没有像Parallel那样以智能方式对范围进行分区。这样做,并逐个处理每个迭代。
  4. 手动使用Partitioner与Partitioner.Create,但它不那么优雅。我希望框架能为我做智能分区。

1 个答案:

答案 0 :(得分:3)

你有一个常规的同步并行循环,你想异步调用它(大概是将它从UI线程移开)。

您可以像移动UI线程中的任何其他CPU绑定工作一样执行此操作:使用Task.Run

public async Task MyMethod()
{
  // Do some preparation

  await Task.Run(() => Parallel.ForEach(0, count, i => { /* Do some work */ }));

  // do some finalization
}

没有线程“浪费”,因为Parallel.ForEach将使用调用线程作为其工作线程之一。

(这是[{3}}中的配方7.4“并行代码的异步包装”)。