我的服务有一个函数,它会触发 web 请求、解析响应并使用响应进行大量计算以最终给出一个集合。
我现在必须对那些进行多次调用以获得许多可以在以后聚合为一个的集合。我想我可以选择其中任何一个Parrallel.ForEach and Tasks.StartNew
您能否建议哪种方法可以有效地处理具有 webrequest 处理和计算的这种情况。
Parrallel.ForEach
并且Tasks.StartNew
适用于受 CPU 限制的工作负载。对于受 I/O 限制的工作负载,您需要异步性,Task.Run(async () => { await ...
现在在您的情况下,您同时拥有受 CPU 和 I/O 限制的工作负载,这是最方便的。好消息是异步基础架构也可以很好地处理受 CPU 限制的工作负载。例如,这是完全有效的:
private async void Button1_Click(object sender, EventArgs args)
{
var webData = await GetWebData(url); // I/O bound
var parsedList = await Task.Run(() => ParseWebData(webData)); // CPU bound
await SaveListToDB(parsedList); // I/O bound
}
I/O 操作期间不会阻塞任何线程,线程池线程将执行 CPU 密集型解析。从可扩展性和资源保护的角度来看,您没有比这更好的了。但是,如果您愿意占用机器的所有资源以获得可能的最佳性能,而不为其他进程留下任何空闲,那么您的策略应该是让所有处理器/内核一直忙碌,同时执行外部世界可以处理的最大并发 I/O 操作数(Web 服务器、文件系统、数据库,对于可以同时执行的工作量都有限制)。
您应该寻找实施此策略的一个好工具是TPL 数据流库,它是 .NET Core 的内置程序,可作为.NET Framework的包提供。如果您对此一无所知,它有一些学习曲线,但不是很陡峭。经过 2-3 天的学习,您会非常有信心用它编写高质量和健壮的生产代码。它拥有拆分、加入、转换、缓冲和并行化工作负载所需的所有工具,让您感觉自己在控制流程,而无需对所有内容进行微观管理。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句