gpt4 book ai didi

c# - Task.StartNew() 与 Parallel.ForEach : Multiple Web Requests Scenario

转载 作者:太空狗 更新时间:2023-10-29 18:31:23 26 4
gpt4 key购买 nike

我已经通读了 SO 中的所有相关问题,但对触发多个 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 的 post据说

"A better solution from a scalability perspective, says Stephen, is totake advantage of asynchronous I/O. When you're calling out acrossthe network, there's no reason (other than convenience) to blocksthreads while waiting for the response to come back"

现有代码似乎消耗了太多线程,处理器时间在生产负载上飙升至 100%,这让我开始思考。

另一种替代方法是使用 Parallel.ForEach,它使用分区程序但也“阻止”调用,这对我的场景来说很好。

考虑到这是所有“异步 IO”工作而不是“CPU 绑定(bind)”工作,并且 Web 请求运行时间不长(最多 3 秒返回),我倾向于认为现有代码已经足够好了。但这会提供比 Parallel.ForEach 更好的吞吐量吗? Parallel.ForEach 可能使用“最小”数量的任务,因为分区和线程的最佳使用(?)。我确实通过一些本地测试对 Parallel.ForEach 进行了测试,但它似乎并没有变得更好。

目标是减少 CPU 时间并增加吞吐量,从而提高可扩展性。是否有更好的方法来并行处理 Web 请求?

感谢任何意见,谢谢。

编辑:代码示例中显示的 ProcessRequest 方法确实使用 HttpClient 及其异步方法来触发请求(PostAsync、GetAsync、PutAsync)。

最佳答案

makes the web request calls (unrelated, so could be fired in parallel)

您真正想要的是并发调用它们,而不是并行。即“同时”,而不是“使用多个线程”。

The existing code appears to consume too many threads

是的,我也这么认为。 :)

Considering this is all "Async IO" work and not "CPU bound" work

那么它应该全部异步完成,使用任务并行或其他并行代码。

正如 Antii 所指出的,您应该使您的异步代码成为异步的:

public async Task ProcessRequestAsync(...);

然后您要做的是使用异步并发 (Task.WhenAll),而不是并行并发 (StartNew /运行/并行):

await Task.WhenAll(list.Select(x => ProcessRequestAsync(x)));

关于c# - Task.StartNew() 与 Parallel.ForEach : Multiple Web Requests Scenario,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30657202/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com