我想知道我们是否应该节流异步任务,如果要完成的任务数量很大。假设您有1000个URL,您是否一次触发所有请求,然后等待所有请求:
var tasks = urlList.Select(url => downloadAsync(url));
await Task.WhenAll(tasks);或者是对请求进行批次处理,然后逐个处理:
foreach (var urlBatch in urlList.BatchEnumerable(BatchSize)){
var tasks = urlBatch.Select(url => downloadAsync(url));
await Task.WhenAll(tasks);
}我认为批处理是不必要的,因为第一种方法(同时触发所有请求)将创建由ThreadPool调度的任务,因此我们应该让ThreadPool决定何时执行每个任务。然而,我被告知,在实践中,只有当任务是计算任务时才能工作。当任务涉及网络请求时,第一种方法可能导致主机挂起?那是为什么?
发布于 2016-01-26 20:56:22
在大多数情况下,你想把自己限制在某件事上。当多个操作同时运行时,总是有一些状态保存在某处。如果它们是CPU绑定的,那么任务将存储在等待线程的ThreadPool队列中,如果是异步的,那么您将状态机放在堆上。
即使异步操作也会消耗有限的资源,包括带宽、端口、远程数据库服务器的CPU等。
不过,您不必一次将自己限制在一个批处理上(因为您需要等待最后一个操作完成,而不是启动其他操作)。您可以使用SlimSemahpore或更好的TPL数据流块进行节流:
var block = new ActionBlock<string>(
url => downloadAsync(url),
new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 10 });
urlList.ForEach(url => block.Post(url));
block.Complete();
await block.Completion;https://stackoverflow.com/questions/35023685
复制相似问题