God*_*ent 6 c# asynchronous iasyncenumerable
我有一个返回异步枚举器的方法
public async IAsyncEnumerable<IResult> DoWorkAsync()
{
await Something();
foreach (var item in ListOfWorkItems)
{
yield return DoWork(item);
}
}
Run Code Online (Sandbox Code Playgroud)
还有来电者:
public async Task LogResultsAsync()
{
await foreach (var result in DoWorkAsync())
{
Console.WriteLine(result);
}
}
Run Code Online (Sandbox Code Playgroud)
因为DoWork这是一项昂贵的操作,我更喜欢以某种方式并行化它,所以它的工作原理类似于:
public async IAsyncEnumerable<IResult> DoWorkAsync()
{
await Something();
Parallel.ForEach(ListOfWorkItems, item =>
{
yield return DoWork(item);
});
}
Run Code Online (Sandbox Code Playgroud)
但是我无法从内部进行收益回报Parallel.Foreach,所以想知道解决这个问题的最佳方法是什么?
返回结果的顺序并不重要。
谢谢。
编辑:抱歉,我遗漏了一些代码DoWorkAsync,它确实在等待我只是没有将其放入上面的代码中,因为这与问题不太相关。现已更新
Edit2: DoWork在我的例子中主要是 I/O 限制,它从数据库读取数据。
AsParallel正如canton7 所建议的,您可以使用Parallel.ForEach.
这可以在标准循环中使用,foreach您可以在其中产生结果:
public async IAsyncEnumerable<IResult> DoWorkAsync()
{
await Something();
foreach (var result in ListOfWorkItems.AsParallel().Select(DoWork))
{
yield return result;
}
}
Run Code Online (Sandbox Code Playgroud)
正如 Theodor Zoulias 所提到的,返回的可枚举实际上根本不是异步的。
如果您只是需要使用 this 来消费它await foreach应该不是问题,但更明确地说,您可以返回IEnumerable并让调用者并行化它:
public async Task<IEnumerable<Item>> DoWorkAsync()
{
await Something();
return ListOfWorkItems;
}
// Caller...
Parallel.ForEach(await DoWorkAsync(), item =>
{
var result = DoWork(item);
//...
});
Run Code Online (Sandbox Code Playgroud)
尽管如果需要在多个地方调用它可能不太容易维护
| 归档时间: |
|
| 查看次数: |
2321 次 |
| 最近记录: |