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

  • 限制异步HTTP请求并发:简单、有效的20个并发下载控制策略已关闭评论
  • 66 次浏览
  • A+
所属分类:.NET技术
摘要

 概述: 通过使用`SemaphoreSlim`,可以简单而有效地限制异步HTTP请求的并发量,确保在任何给定时间内不超过20个网页同时下载。`ParallelOptions`不适用于异步操作,但可考虑使用`Parallel.ForEach`,尽管在异步场景中谨慎使用。

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

 

概述:通过使用`SemaphoreSlim`,可以简单而有效地限制异步HTTP请求的并发量,确保在任何给定时间内不超过20个网页同时下载。`ParallelOptions`不适用于异步操作,但可考虑使用`Parallel.ForEach`,尽管在异步场景中谨慎使用。

对于并发异步 I/O 操作的数量限制,可以使用SemaphoreSlim,但由于AsParallel 使用的是 PLINQ(Parallel LINQ),而 PLINQ 不太适用于异步操作。因此,我们可以使用异步的 Task.WhenAll 和 SemaphoreSlim 来实现并发控制。同时,ParallelOptions 不适用于异步操作,因为它主要用于同步的 Parallel 类库。

以下是一个使用 SemaphoreSlim 的示例,以确保在任何给定时间下载的网页不超过 20 个:

using System; using System.Net.Http; using System.Threading; using System.Threading.Tasks;  class Program {     static async Task Main()     {         string[] urls = { "http://google.com", "http://yahoo.com", /*...*/ };          // 设置最大并发数为20         int maxConcurrency = 20;         var semaphore = new SemaphoreSlim(maxConcurrency);          var tasks = urls.Select(url => DownloadUrlAsync(url, semaphore));          await Task.WhenAll(tasks);     }      static async Task DownloadUrlAsync(string url, SemaphoreSlim semaphore)     {         await semaphore.WaitAsync();          try         {             var client = new HttpClient();             var html = await client.GetStringAsync(url);             // 处理获取的 HTML 数据             Console.WriteLine($"Downloaded {url} successfully");         }         catch (Exception ex)         {             // 处理异常             Console.WriteLine($"Error downloading {url}: {ex.Message}");         }         finally         {             semaphore.Release();         }     } }

在这个例子中,SemaphoreSlim 用于限制并发异步 I/O 操作的数量。WaitAsync 方法用于获取信号,Release 方法用于释放信号。这确保了在任何给定时间内,同时运行的异步操作数量不会超过 maxConcurrency 指定的最大并发数。

如果你想使用 ParallelOptions,你可以考虑使用 Parallel.ForEach,但要注意这仍然适用于同步操作。以下是一个示例:

using System; using System.Net.Http; using System.Threading; using System.Threading.Tasks;  class Program {     static async Task Main()     {         string[] urls = { "http://google.com", "http://yahoo.com", /*...*/ };          // 设置最大并发数为20         int maxConcurrency = 20;          Parallel.ForEach(urls, new ParallelOptions { MaxDegreeOfParallelism = maxConcurrency }, async (url) =>         {             var client = new HttpClient();             var html = await client.GetStringAsync(url);             // 处理获取的 HTML 数据             Console.WriteLine($"Downloaded {url} successfully");         });     } }

上述代码使用的 Parallel.ForEach 并不能直接处理异步委托,因此需要谨慎使用。在异步场景中,使用 SemaphoreSlim 进行手动并发控制可能是更可靠的选择。

 

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