Geo*_*uer 1 c# linq parallel-extensions task-parallel-library async-await
我不确定我应该如何混合plinq和async-await.假设我有以下界面
public interface IDoSomething (
Task Do();
}
Run Code Online (Sandbox Code Playgroud)
我有一个列表,我想并行执行,并能够await完成所有这些.
public async Task DoAll(IDoSomething[] doers) {
//Execute all doers in parallel ideally using plinq and
//continue when all are complete
}
Run Code Online (Sandbox Code Playgroud)
怎么实现这个?我不知道如何从并行linq转到任务,反之亦然.
我对异常处理并不十分担心.理想情况下,第一个会触发并打破整个过程,因为我打算在出错时抛弃整个过程.
编辑:很多人都说Task.WaitAll.我知道这一点,但我的理解(除非有人能证明不是这样)是因为它不能主动将你的东西并行化到多个可用的处理器核心.我特别要问的是双重的 -
如果我await一个Task一个PLINQ行动中确实是摆脱由于日程安排一个新的线程有很多的优势的?
如果我doers.AsParallel().ForAll(async d => await d.Do())平均需要大约5秒钟,那么在此期间我怎么不旋转调用线程呢?
您正在寻找的是:
public Task DoAllAsync(IEnumerable<IDoSomething> doers)
{
return Task.WhenAll(doers.Select(doer => Task.Run(() => doer.Do())));
}
Run Code Online (Sandbox Code Playgroud)
使用Task.Run将使用一个ThreadPool线程来执行的每个同步部分async方法Do在并行而Task.WhenAll异步地等待异步部分一起被同时执行.
只有在这些async方法中具有大量同步部件(await例如,之前的部件)时,这是一个好主意,例如:
async Task Do()
{
for (int i = 0; i < 10000; i++)
{
Math.Pow(i,i);
}
await Task.Delay(10000);
}
Run Code Online (Sandbox Code Playgroud)
否则,不需要并行性,您可以同时触发异步操作并等待所有返回的任务Task.WhenAll:
public Task DoAllAsync(IEnumerable<IDoSomething> doers)
{
return Task.WhenAll(doers.Select(doer => doer.Do()));
}
Run Code Online (Sandbox Code Playgroud)