![](/img/trans.png)
[英]How to run a Parallel.ForEachAsync loop with NoBuffering?
[英]How To Set Minimum Degree Of Parallelism For Parallel.ForEachAsync
假設我有以下 C# 代碼,它並行發送對某些 url 數組的獲取請求:
internal class Program
{
static async Task Main(string[] args)
{
string[] urls = { "https://example1.com", "https://example2.com", "https://example3.com", "https://example4.com", "https://example5.com" };
HttpClientHandler clientHandler = new HttpClientHandler();
using (var client = new HttpClient(clientHandler))
{
client.Timeout = TimeSpan.FromSeconds(10);
var options = new ParallelOptions { MaxDegreeOfParallelism = urls.Length };
await Parallel.ForEachAsync(urls, options, async (url, stoppingToken) =>
{
try
{
Console.WriteLine("Processing " + url);
HttpResponseMessage response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
var resp = await response.Content.ReadAsStringAsync();
Console.WriteLine("Response for " + url + " " + resp);
}
catch (Exception ex)
{
Console.WriteLine("Response for " + url + " " + ex.Message);
}
});
Console.WriteLine("Completed");
}
Console.ReadLine();
}
}
如果我將 MaxDegreeOfParallelism 設置為數組的大小,這是否也作為隱含的最小並行度? 意思是,我的代碼會嘗試生成與 MaxDegreeOfParallelism 值相同數量的線程嗎?
編輯 1
如果沒有,我可以用下面的代碼實現類似的東西嗎:
internal class Program
{
public async Task sendRequest(string url)
{
HttpClientHandler clientHandler = new HttpClientHandler();
using (var client = new HttpClient(clientHandler))
{
client.Timeout = TimeSpan.FromSeconds(10);
try
{
Console.WriteLine("Processing " + url);
HttpResponseMessage response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
var resp = await response.Content.ReadAsStringAsync();
Console.WriteLine("Response for " + url + " " + resp);
}
catch (Exception ex)
{
Console.WriteLine("Response for " + url + " " + ex.Message);
}
}
}
static async Task Main(string[] args)
{
string[] urls = { "https://example1.com", "https://example2.com", "https://example3.com", "https://example4.com", "https://example5.com" };
foreach (string url in urls)
{
Program program = new Program();
//dont await the sendRequest() method so that you can go through whole loop
Thread operation = new Thread(() => program.sendRequest(url));
operation.Start();
}
Console.ReadLine();
}
}
MaxDegreeOfParallelism 到數組的大小,這是否也作為隱含的最小並行度?
不。沒有“最小並行度”,因為即使在單核 CPU 上,代碼仍應運行。
我的代碼會嘗試生成與 MaxDegreeOfParallelism 值相同數量的線程嗎?
不,允許使用與MaxDegreeOfParallelism
一樣多的線程,但不是必須的。 使用比邏輯 CPU 內核更多的線程對於計算受限的工作負載來說效率低下,因此它會盡量保持線程數盡可能小,同時仍然使用盡可能多的 CPU,但我不確定具體細節。 除非您有其他原因,否則我建議您不要設置MaxDegreeOfParallelism
並讓循環使用其默認行為。
請注意,並行循環的主要好處是在運行計算綁定代碼時。 您的示例似乎嚴格受 IO 約束,因此可能不會比使用這樣的方法獲得太多好處:
await Task.WhenAll(urls.Select(async url => {...}));
這將順序啟動所有請求,讓請求並發運行,然后再次順序處理結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.