鉴于我有一个IEnumerable<Func<Task>>
来生成一些我想同时执行的(抓取)任务,如何为并发设置上限?
例如,我不希望同时运行5个以上的任务。另一方面,如果可能的话,总是应该有5个任务在运行。
我当前的方法是这段代码:
public static async Task ExecuteConcurrent(IEnumerable<Func<Task>> taskGenerators, int maxDegreeOfConcurrency)
{
var executingTasks = new HashSet<Task>();
foreach (var taskGenerator in taskGenerators) {
while (executingTasks.Count >= maxDegreeOfConcurrency) {
executingTasks.Remove(await Task.WhenAny(executingTasks));
}
executingTasks.Add(taskGenerator());
}
await Task.WhenAll(executingTasks);
}
我想知道是否有更好的方法可以做到这一点?也许已经有一种方法可用了?
谢谢
答案 0 :(得分:2)
听起来像TPL Dataflow的工作
优点是:
async
和await
以及 CPU约束和 IO约束工作负载都很好地工作MaxDegreeOfParallelism
和许多其他选项来限制并发性Nuget System.Threading.Tasks.Dataflow
非常基本的示例
public static async Task DoWorkLoads(List<IPAddress> addresses)
{
var options = new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = 50 // limit here
};
var block = new ActionBlock<SomeObject>(MyMethodAsync, options);
foreach (var ip in addresses)
block.Post(ip);
block.Complete();
await block.Completion;
}
...
public async Task MyMethodAsync(SomeObject obj)
{
// await something here
}