c# - “无限”异步并行 foreach 循环
问题描述
我有一个List<string>
包含 50K 到 100K 字的
我想以并行和异步的方式迭代它
例如,我可以使用
while (true)
{
Parallel.ForEach(words, new ParallelOptions { MaxDegreeOfParallelism = 100 }, ...)
}
但问题是:
Parallel.ForEach
不是异步的- 当我们到达列表的末尾时,我们必须等待每个线程结束,然后
while (true)
语句才能继续 - 这意味着并不总是有100 个线程在运行,这就是我想要的
我怎么能做到这一点?
请让我知道这是否令人困惑,或者我是否不擅长解释事情。
解决方案
这是一个完全人为设计的async
友好TPL DataFlow示例,说明如何实现您的要求。
- 它适用于异步 IO 工作负载
- 是可以取消的
- 它限制了最大并行度
- 它有有限的容量,所以总是有 100 个工作可用
- 是无限的
给定
private static CancellationTokenSource _cs;
private static CancellationToken _token;
private static ActionBlock<string> _block;
private static async Task MethodAsync(string something)
{
// Your async workload
}
public static async Task EndlessRunner(string[] someArray)
{
try
{
var index = 0;
while (!_token.IsCancellationRequested)
{
await _block.SendAsync(someArray[index],_token);
if (++index >= someArray.Length) index = 0;
}
}
catch (OperationCanceledException)
{
Console.WriteLine("Cancelled");
}
}
例子
private static async Task Main()
{
_cs = new CancellationTokenSource();
_token = _cs.Token;
_block = new ActionBlock<string>(
MethodAsync,
new ExecutionDataflowBlockOptions()
{
EnsureOrdered = false,
MaxDegreeOfParallelism = 100,
BoundedCapacity = 100,
CancellationToken = _cs.Token,
SingleProducerConstrained = true
});
var someList = Enumerable
.Range(0,5000)
.Select(I => $"something {I}")
.ToArray();
Task.Run(() => EndlessRunner(someList));
Console.ReadKey();
_cs.Cancel();
_block.Complete();
await _block.Completion;
}
推荐阅读
- oracle - oracle游标并发插入stmt
- plot - 全息视图;时间序列图不显示
- html - 有人可以帮我将媒体查询从最大宽度更改为最小宽度吗?
- mysql - 需要避免 join 中的乘法 sum()
- java - Vaadin Flow - 使用样式表“themeFor”创建自己的组件
- reactjs - 如何在我的 reactjs 应用程序中跟踪错误的来源?
- python - tkinter Python 保存用户输入以备将来使用
- javascript - PayPal 智能按钮将项目描述添加到按钮
- asp.net - 如何使用 Visual Studio 19 从网站步入 WCF asp.net 服务应用程序
- python - 无法在 python selenium 中使用 is_displayed 属性