【发布时间】:2014-12-22 01:12:09
【问题描述】:
我不确定我应该如何混合 plinq 和 async-await。假设我有如下界面
public interface IDoSomething (
Task Do();
}
我有一个列表,我想并行执行并能够await 完成所有操作。
public async Task DoAll(IDoSomething[] doers) {
//Execute all doers in parallel ideally using plinq and
//continue when all are complete
}
如何实现?我不确定如何从并行 linq 转到 Tasks,反之亦然。
我并不十分担心异常处理。理想情况下,第一个会触发并破坏整个过程,因为我计划在出错时丢弃整个过程。
编辑:很多人都在说Task.WaitAll。我知道这一点,但我的理解(除非有人可以证明)是它不会主动为您将事情并行化到多个可用的处理器内核。我具体要问的是双重的 -
如果我在 Plinq 操作中
await和Task是否会失去很多优势,因为它会安排一个新线程?如果我
doers.AsParallel().ForAll(async d => await d.Do())平均需要大约 5 秒,我如何不同时旋转调用线程?
【问题讨论】:
-
await Task.WhenAll(....) -
当被问到“并行异步代码”的问题时,正确的答案通常是TPL Dataflow。但是一个简单的
Task.WhenAll结合Task.Runs 可能就足够了,就像@l3arnon 的回答一样。 -
@GeorgeMauer:PLINQ 用于并行化 CPU 密集型工作。 Async/await 用于并发异步工作(通常是 I/O-bound)。异步等待并行工作完成 (
await Task.Run(() => { /* parallel stuff */ })) 是有意义的,但尝试并行化异步(通常是 I/O 绑定)工作就没有意义了。WhenAll本身可以给你异步并发,或者WhenAll包装Task.Runs 可以给你一种异步并行foreach。但是,您实际上需要是极其罕见的。 -
@GeorgeMauer:顺便说一句,我尽量不在这里做自我广告,但老实说,我认为你会从my book 中受益。我将讨论并发、异步、并行、TPL 数据流、Rx 以及它们如何协同工作。
标签: c# linq task-parallel-library async-await parallel-extensions