限定异步HTTP请求并发:简单、有效的20个并发下载控制策略 ...

打印 上一主题 下一主题

主题 834|帖子 834|积分 2502

 
概述:通过利用`SemaphoreSlim`,可以简单而有效地限定异步HTTP请求的并发量,确保在任何给定时间内不超过20个网页同时下载。`ParallelOptions`不实用于异步操纵,但可考虑利用`Parallel.ForEach`,只管在异步场景中谨慎利用。
对于并发异步 I/O 操纵的数量限定,可以利用SemaphoreSlim,但由于AsParallel 利用的是 PLINQ(Parallel LINQ),而 PLINQ 不太实用于异步操纵。因此,我们可以利用异步的 Task.WhenAll 和 SemaphoreSlim 来实现并发控制。同时,ParallelOptions 不实用于异步操纵,因为它主要用于同步的 Parallel 类库。
以下是一个利用 SemaphoreSlim 的示例,以确保在任何给定时间下载的网页不超过 20 个:
  1. using System;
  2. using System.Net.Http;
  3. using System.Threading;
  4. using System.Threading.Tasks;
  5. class Program
  6. {
  7.     static async Task Main()
  8.     {
  9.         string[] urls = { "http://google.com", "http://yahoo.com", /*...*/ };
  10.         // 设置最大并发数为20
  11.         int maxConcurrency = 20;
  12.         var semaphore = new SemaphoreSlim(maxConcurrency);
  13.         var tasks = urls.Select(url => DownloadUrlAsync(url, semaphore));
  14.         await Task.WhenAll(tasks);
  15.     }
  16.     static async Task DownloadUrlAsync(string url, SemaphoreSlim semaphore)
  17.     {
  18.         await semaphore.WaitAsync();
  19.         try
  20.         {
  21.             var client = new HttpClient();
  22.             var html = await client.GetStringAsync(url);
  23.             // 处理获取的 HTML 数据
  24.             Console.WriteLine($"Downloaded {url} successfully");
  25.         }
  26.         catch (Exception ex)
  27.         {
  28.             // 处理异常
  29.             Console.WriteLine($"Error downloading {url}: {ex.Message}");
  30.         }
  31.         finally
  32.         {
  33.             semaphore.Release();
  34.         }
  35.     }
  36. }
复制代码
在这个例子中,SemaphoreSlim 用于限定并发异步 I/O 操纵的数量。WaitAsync 方法用于获取信号,Release 方法用于开释信号。这确保了在任何给定时间内,同时运行的异步操纵数量不会超过 maxConcurrency 指定的最大并发数。
假如你想利用 ParallelOptions,你可以考虑利用 Parallel.ForEach,但要注意这仍然实用于同步操纵。以下是一个示例:
  1. using System;
  2. using System.Net.Http;
  3. using System.Threading;
  4. using System.Threading.Tasks;
  5. class Program
  6. {
  7.     static async Task Main()
  8.     {
  9.         string[] urls = { "http://google.com", "http://yahoo.com", /*...*/ };
  10.         // 设置最大并发数为20
  11.         int maxConcurrency = 20;
  12.         Parallel.ForEach(urls, new ParallelOptions { MaxDegreeOfParallelism = maxConcurrency }, async (url) =>
  13.         {
  14.             var client = new HttpClient();
  15.             var html = await client.GetStringAsync(url);
  16.             // 处理获取的 HTML 数据
  17.             Console.WriteLine($"Downloaded {url} successfully");
  18.         });
  19.     }
  20. }
复制代码
上述代码利用的 Parallel.ForEach 并不能直接处理异步委托,因此需要谨慎利用。在异步场景中,利用 SemaphoreSlim 进行手动并发控制大概是更可靠的选择。
 



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

雁过留声

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表