如何使用任务并行库制作大量HTTP请求

本文关键字:HTTP 请求 何使用 任务 并行 | 更新日期: 2023-09-27 18:01:18

我是。net框架的任务并行库(以及一般的多任务和多线程)的新手。从我读过的文献来看,我应该能够创建一堆任务,运行它们,框架应该负责生成必要数量的根据系统上可用的资源分配线程。我遇到的问题是及时发出数千个HTTP请求。这就是我的代码

var taskList = new List<Task>();
foreach(var request in requests)
{
     taskList.Add(client.SendAsync(request));
}
Task.WaitAll(taskList.ToArray());

clientSystem.Net.Http.HttpClient对象。我使用Task.WaitAll(),因为这段代码是在一个方法,不是异步的。为了测试此代码,我向同一局域网上的另一台服务器发出请求。请求集合超过15,000个,因此应该为每个对象创建一个任务。但在抛出聚合异常之前,它只能运行大约7000个线程。内部异常似乎不是很有帮助,只是陈述"任务被取消"尽管取消令牌报告没有请求取消。堆栈跟踪也不是很有帮助,最近的调用显示为:

在System.Threading.Tasks.Task

。WaitAll(Task[] tasks, Int32毫秒超时,CancellationToken在System.Threading.Tasks.Task。WaitAll(Task[] tasks, Int32millisecondsTimeout)
在System.Threading.Tasks.Task。WaitAll[]任务(任务)

我也玩了Parallel.Invoke(),但事实证明更糟。

var taskActionList = new List<Action>();
foreach(var request in requests)
{
    taskActionList.Add(() => client.SendAsync(request));
}
Parallel.Invoke(taskActionList.ToArray());

这不会抛出任何异常,但它只运行大约1,300个任务和代码运行到完成。

我的问题是,你如何使用任务并行库来有效地制作大量的HTTP请求?我是不是漏掉了什么?

如何使用任务并行库制作大量HTTP请求

TPL不知道如何最好地调度HTTP调用。它甚至不知道您正在执行IO。启发式是不够的。

通常,IO的可选并行度需要通过实验来确定。您需要编写代码,以便使用这个最佳DOP。没有任何内置构造可以为您提供确切的DOP。它总是最大值。

这里,某些东西过载导致超时。取消异常通常是超时的标志(是的,这是有问题的API设计)。

您可以使用ForEachAsync

requests.ForEachAsync(async () => await ProcessAsync(request)).Wait();