咨询区

  • Grief Coder

我的项目中有下面一段代码:

// let's say there is a list of 1000+ URLs
string[] urls = { "http://google.com", "http://yahoo.com", ... };// now let's send HTTP requests to each of these URLs in parallel
urls.AsParallel().ForAll(async (url) => {var client = new HttpClient();var html = await client.GetStringAsync(url);
});

这段代码有一个问题,当我开启了 1000+ 的并发请求,是否有一种简便的方式限制这些 异步http请求 并发量,比如说实现同一时刻不会超过 20 个下载,请问我该如何去实现?

回答区

  • Jay Shah

可以使用 SemaphoreSlim,它可以非常完美的搞定,下面是我实现的扩展方法。

public static async Task ForEachAsyncConcurrent<T>(this IEnumerable<T> enumerable,Func<T, Task> action,int? maxActionsToRunInParallel = null){if (maxActionsToRunInParallel.HasValue){using (var semaphoreSlim = new SemaphoreSlim(maxActionsToRunInParallel.Value, maxActionsToRunInParallel.Value)){var tasksWithThrottler = new List<Task>();foreach (var item in enumerable){// Increment the number of currently running tasks and wait if they are more than limit.await semaphoreSlim.WaitAsync();tasksWithThrottler.Add(Task.Run(async () =>{await action(item).ContinueWith(res =>{// action is completed, so decrement the number of currently running taskssemaphoreSlim.Release();});}));}// Wait for all of the provided tasks to complete.await Task.WhenAll(tasksWithThrottler.ToArray());}}else{await Task.WhenAll(enumerable.Select(item => action(item)));}}

然后像下面这样使用。

await enumerable.ForEachAsyncConcurrent(async item =>{await SomeAsyncMethod(item);},5);
  • Serge Semenov

其实直接用 semaphore 稍不注意就会遇到很多的坑,而且排查起来还特别棘手,我建议你使用 AsyncEnumerator NuGet Package ,参考地址:https://www.nuget.org/packages/AsyncEnumerator/1.1.0  ,这样也不需要再造什么轮子了,参考如下代码:

using System.Linq;
using System.Buffers;
using Dasync.Collections;// let's say there is a list of 1000+ URLs
string[] urls = { "http://google.com", "http://yahoo.com"};// now let's send HTTP requests to each of these URLs in parallel
await urls.ParallelForEachAsync(async (url) => {var client = new HttpClient();var html = await client.GetStringAsync(url);
},maxDegreeOfParallelism: 20);

点评区

在异步上做并发限制要比同步复杂的多,不过也是有一些可选方式,比如本篇的这两种,学习了。

如何限制并发的 异步IO 请求数量?相关推荐

  1. 【进阶】 --- 多线程、多进程、异步IO实用例子

    [进阶] --- 多线程.多进程.异步IO实用例子:https://blog.csdn.net/lu8000/article/details/82315576 python之爬虫_并发(串行.多线程. ...

  2. 并发模型与IO模型梳理

    并发模型 常见的并发模型一般包括3类,基于线程与锁的内存共享模型,actor模型和CSP模型,其中尤以线程与锁的共享内存模型最为常见.由于go语言的兴起,CSP模型也越来越受关注.基于锁的共享内存模型 ...

  3. [进阶]-多线程、多进程、异步IO实用例子

    在编写爬虫时,性能的消耗主要在IO请求中,当单进程单线程模式下请求URL时必然会引起等待,从而使得请求整体变慢.以下代码默认运行环境为python3. 目录 一.多线程.多进程 1.同步执行 2.多线 ...

  4. 高性能异步IO机制:IO_URING

    高性能异步IO机制:IO_URING 一.前言 1.1 异步IO机制 Linux内核提供的IO机制大都是同步实现的,如常规的read/write/send/recv等系统调用.同步IO机制存在着一定的 ...

  5. 异步IO一定更好吗?

    http://cnodejs.org/blog/?p=1015 续:异步IO一定更好吗? 我之前的一篇文章<异步IO一定更好吗?>中举了一个很变态的例子,用以说明在单碟机械式硬盘上异步IO ...

  6. Linux异步IO实现方案总结

    一.glibc aio 1.名称 由于是glibc提供的aio函数库,所以称为glibc aio. glibc是GNU发布的libc库,即c运行库. 另外网上还有其他叫法posix aio,都是指gl ...

  7. python异步的发展历程_深入了解Python的异步IO:概念和历史

    前面发表了<简说Python Web异步框架>一文后,很多朋友希望能更多了解Python关于asyncio的知识.正好,我也想深入理解理解这方面的知识,于是就促成了这篇文章. 一.软件系统 ...

  8. 【免杀前置课——Windows编程】十四、异步IO——什么是异步IO、API定位问题、APC调用队列

    异步IO 异步IO 异步I/0注意事项: 定位问题 总解决方案 APC调用队列 异步IO 当我们读取一个文件时,一般情况下,线程是阻塞的,也就是说,当前线程在等待文件读取操作结束,这种方式叫同步IO. ...

  9. windows下异步IO一

    介绍 简单讲解下我们程序进行IO的过程,当线程进行一个同步的设备IO请求时,他会被挂起,直到设备完成IO请求,返回给阻塞线程,线程激活继续处理.当进行一个异步的设备IO请求时,该线程可以先去做其他事, ...

最新文章

  1. php改7z,PHP的7z扩展名? - php
  2. Rust 语言风靡学术界
  3. NLP语言模型任务数据准备及实战
  4. java内外循环打印等腰三角*号
  5. 弹出窗口显示输出内容_前端加油站(3)-JavaScript 输出
  6. nodejs unhandledPromiseRejectionWarning警告信息
  7. 学习Python可以从事哪些工作?
  8. SpringBoot在线预览PDF文件
  9. 非线性声学回声消除技术
  10. 为什么高斯滤波器被广泛用于图像处理?
  11. Vue学习(一)从 mvx模式 到 mvvm模式
  12. adobe xd_如何在Adobe XD中创建Finance App UI设计
  13. linux下启动,关闭oracle数据库
  14. 如何批量提取过期域名,如何批量查询权重域名、收录域名
  15. 黑马程序员中的简单网页制作
  16. excel 数据透视表,笔记6,权亮
  17. IC卡,ID卡,M1卡,射频卡
  18. python学习——每日一句
  19. The Sandbox 市场平台将上线 Isla Obscura 第五期 NFT 作品集
  20. 成都芝加哥大学计算机专业,芝加哥大学研究生计算机专业排名怎么样?_托普仕留学...

热门文章

  1. fastdfs 一个group内实现按照不同的项目,指定路径存储.
  2. 一句命令行检查cpu个数
  3. asp版新闻发布今日弄好
  4. CentOS系统更换yum源(repomd.xml not found解决方案)
  5. C++中STL的一些用法的补充
  6. iOS AVPlayer 简单应用
  7. python3-day4(装饰器)
  8. Echart..js插件渲染报错 data.length1?
  9. Java设计模式(8)组合模式(Composite模式)
  10. 【C++ Primer学习笔记】第2章:变量和基本类型