并行和异步方法

时间:2014-06-28 14:16:41

标签: c# loops parallel-processing execution

我有一个简单的问题 - 为什么异步方法不等待并行循环完成?

public async Task<List<object>> DoSomeAsync()
{
   // some async actions with streams and web requests
   // ...
   ConcurrentQueue<object> queue = new ConcurrentQueue<object>();    

   Parallel.For(1, x, async i => 
   {
      // a little chunk of code
      // ...
      queue.Enqueue(new object());
      // ...
      // a little chunk of code again
   }

   return queue.ToList(); // debugger says that this statement is executed earlier than parallel loop.
}

你知道我怎么能等待并行循环的执行?

2 个答案:

答案 0 :(得分:1)

只需在没有'async'的情况下使用它:在移动到下一行之前,它将是确保程序完成的最简单方法,仍处于并行执行模式(换句话说,它会阻止主UI等待完成工作进程,它本身以并行模式运行一些东西):

   Parallel.For(1, x, (i) => 
   {
      // a little chunk of code
      // ...
      queue.Enqueue(new object());
      // ...
      // a little chunk of code again
   });

此外,您可以查看Alexandra Rusina(http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx)使用Task.Factory.ContinueWhenAll()给出的示例(适用于您的问题)(如果以并行/异步模式运行)。 RGDS,

答案 1 :(得分:-1)

由于Parallel.For理想地并行执行多个任务,因此等待单个任务是没有意义的,因为这本身会序列化它们的执行。为什么ParallelLoopResult不是Task的子类,虽然对我来说是一个谜。虽然你可以做类似

的事情
await Task.Run(() => Parallel.For(...)
由于你已经处于异步方法,并且你的线程或由Task.Run创建的线程是阻塞Parallel.For的线程在此时无关紧要,所以它不会给你任何购买。

我能想到的最好的是ParallelLoopResult是以这样的方式编写的,它需要一个线程来坐下来收集循环的状态。