首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >节流异步任务?

节流异步任务?
EN

Stack Overflow用户
提问于 2016-01-26 20:49:51
回答 1查看 1K关注 0票数 5

我想知道我们是否应该节流异步任务,如果要完成的任务数量很大。假设您有1000个URL,您是否一次触发所有请求,然后等待所有请求:

代码语言:javascript
复制
var tasks = urlList.Select(url => downloadAsync(url));
await Task.WhenAll(tasks);

或者是对请求进行批次处理,然后逐个处理:

代码语言:javascript
复制
foreach (var urlBatch in urlList.BatchEnumerable(BatchSize)){
    var tasks = urlBatch.Select(url => downloadAsync(url));
    await Task.WhenAll(tasks);
}

我认为批处理是不必要的,因为第一种方法(同时触发所有请求)将创建由ThreadPool调度的任务,因此我们应该让ThreadPool决定何时执行每个任务。然而,我被告知,在实践中,只有当任务是计算任务时才能工作。当任务涉及网络请求时,第一种方法可能导致主机挂起?那是为什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-26 20:56:22

在大多数情况下,你想把自己限制在某件事上。当多个操作同时运行时,总是有一些状态保存在某处。如果它们是CPU绑定的,那么任务将存储在等待线程的ThreadPool队列中,如果是异步的,那么您将状态机放在堆上。

即使异步操作也会消耗有限的资源,包括带宽、端口、远程数据库服务器的CPU等。

不过,您不必一次将自己限制在一个批处理上(因为您需要等待最后一个操作完成,而不是启动其他操作)。您可以使用SlimSemahpore或更好的TPL数据流块进行节流:

代码语言:javascript
复制
var block = new ActionBlock<string>(
   url => downloadAsync(url),
   new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 10 });    

urlList.ForEach(url => block.Post(url));

block.Complete();
await block.Completion;
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35023685

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档