![](/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.