【发布时间】:2016-12-12 23:51:22
【问题描述】:
我是 .NET 框架的任务并行库(以及一般的多任务和多线程)的新手。 从我读过的文献来看,我应该能够创建一堆任务, 运行它们,框架应该负责产生必要数量的 线程根据系统上可用的资源。 我遇到的问题是及时发出数千个 HTTP 请求。 这就是我的代码。
var taskList = new List<Task>();
foreach(var request in requests)
{
taskList.Add(client.SendAsync(request));
}
Task.WaitAll(taskList.ToArray());
client 是一个 System.Net.Http.HttpClient 对象。
我正在使用Task.WaitAll(),因为此代码位于非异步方法中。
为了测试此代码,我向同一 LAN 上的另一台服务器发出请求。
requests 集合有超过 15,000 个,因此应该为每个对象创建一个任务。
但它在引发聚合异常之前只能运行大约 7,000 次。内部异常似乎不是很有帮助,仅说明
“任务被取消”
尽管取消令牌报告未请求取消。
堆栈跟踪也不是很有帮助,最近的调用显示为:
在 System.Threading.Tasks.Task.WaitAll(Task[] 任务,Int32 毫秒超时,CancellationToken 取消令牌) 在 System.Threading.Tasks.Task.WaitAll(任务 [] 任务,Int32 毫秒超时)
在 System.Threading.Tasks.Task.WaitAll(Task[] 任务)
我也玩过Parallel.Invoke(),但事实证明情况更糟。
var taskActionList = new List<Action>();
foreach(var request in requests)
{
taskActionList.Add(() => client.SendAsync(request));
}
Parallel.Invoke(taskActionList.ToArray());
这不会引发任何异常,但它只运行大约 1,300 个任务,并且 代码运行完成。
我的问题是,你如何使用任务并行库来有效地使 大量的 HTTP 请求?有什么我遗漏的吗?
【问题讨论】:
-
我担心任务并行库与您尝试的
async - await方法无关。 -
您得到的异常可能是因为某些请求已超时。您在很短的时间内发送了大量请求,您应该预料到会发生这种情况。如果一个请求超时怎么办?此外,您是否应该将任何给定时刻的活动请求数限制为合理的数量,例如10 点?
标签: c# .net parallel-processing