我已经阅读了SO中所有相关的问题,但是对于我的场景最佳方法有些困惑,因为需要同时发出多个web服务调用。
我有一个聚合器服务,它接收一个输入,解析并将其转换为多个Web请求,进行Web请求调用(不相关,因此可以并行调用),并汇总响应,然后将其发送回调用方。目前使用以下代码:
list.ForEach((object obj) =>
{
tasks.Add(Task.Factory.StartNew((object state) =>
{
this.ProcessRequest(obj);
}, obj, CancellationToken.None,
TaskCreationOptions.AttachedToParent, TaskScheduler.Default));
});
await Task.WhenAll(tasks);
await Task.WhenAll(tasks)
来自Scott Hanselman的文章,其中提到:
"从可扩展性的角度来看,一个更好的解决方案是利用异步I/O。当你在跨网络调用时,没有理由(除了方便)阻塞线程等待响应返回"
现有代码似乎消耗了太多的线程,生产负载下处理器时间飙升至100%,这让我开始思考。
另一个选择是使用Parallel.ForEach,它使用分区器但也会“阻塞”调用,对于我的情况来说这是可以接受的。
考虑到这都是“异步I/O”工作而不是“CPU绑定”工作,并且Web请求不会长时间运行(最多3秒返回),我倾向于认为现有代码已经足够好了。但是,与Parallel.ForEach相比,这是否能提供更好的吞吐量?Parallel.ForEach可能使用“最小”数量的任务,因为分区,因此可以最优地利用线程(?)。我进行了一些本地测试并没有发现Parallel.ForEach更好。
目标是减少CPU时间并增加吞吐量,从而实现更好的可扩展性。是否有更好的处理Web请求并行的方法?
非常感谢任何意见,谢谢。
编辑: 代码示例中显示的ProcessRequest方法确实使用HttpClient及其异步方法来触发请求(PostAsync、GetAsync、PutAsync)。