我有一个简单的问题 - 为什么异步方法不等待并行循环完成?
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.
}
你知道我怎么能等待并行循环的执行?
答案 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
是以这样的方式编写的,它需要一个线程来坐下来收集循环的状态。