并行for循环和异步方法

4
我有一个简单的问题 - 为什么异步方法不等待并行循环完成呢?
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.
}

你知道如何等待并行循环执行的方法吗?


可能需要使用 await Parallel.For(...) - Grundy
5
无法等待并行循环,因为它们不会返回任务实例。 - vdrake6
Parallel.For 循环内部是否有任何可等待的方法? - George Chondrompilas
你显然不理解async和await的作用。如果在不理解的情况下使用这些特性,你将会遇到很多意外。 - usr
2个回答

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()解决了您的问题(在并行/异步模式下运行)。敬礼。

-1

由于Parallel.For理想情况下并行执行多个任务,因此等待单个任务就没有意义,因为这会固有地序列化它们的执行。尽管如此,我仍然不明白为什么ParallelLoopResult不是Task的子类。虽然你可以做一些事情,比如

await Task.Run(() => Parallel.For(...)

这并没有什么用,因为您已经在异步方法中了,无论是您的线程还是由Task.Run创建的线程都无关紧要,它们都会阻塞Parallel.For

我能想到的最好的解释是ParallelLoopResult被编写成需要一个线程来收集循环状态。


"它将什么都买不到" - usr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接