gpt4 book ai didi

c# - 如何正确排队要在 C# 中运行的任务

转载 作者:IT王子 更新时间:2023-10-29 04:42:38 27 4
gpt4 key购买 nike

我有一个项目枚举 (RunData.Demand),每个项目代表一些涉及通过 HTTP 调用 API 的工作。如果我只是 foreach 遍历所有内容并在每次迭代期间调用 API,效果会很好。但是,每次迭代需要一两秒钟,所以我想运行 2-3 个线程并在它们之间分配工作。这是我正在做的:

ThreadPool.SetMaxThreads(2, 5); // Trying to limit the amount of threads
var tasks = RunData.Demand
.Select(service => Task.Run(async delegate
{
var availabilityResponse = await client.QueryAvailability(service);
// Do some other stuff, not really important
}));

await Task.WhenAll(tasks);

client.QueryAvailability 调用基本上使用 HttpClient 类调用 API:

public async Task<QueryAvailabilityResponse> QueryAvailability(QueryAvailabilityMultidayRequest request)
{
var response = await client.PostAsJsonAsync("api/queryavailabilitymultiday", request);

if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsAsync<QueryAvailabilityResponse>();
}

throw new HttpException((int) response.StatusCode, response.ReasonPhrase);
}

这在一段时间内效果很好,但最终事情开始超时。如果我将 HttpClient 超时设置为一个小时,我就会开始收到奇怪的内部服务器错误。

我开始做的是在 QueryAvailability 方法中设置秒表以查看发生了什么。

发生的事情是一次创建 RunData.Demand 中的所有 1200 个项目,并调用所有 1200 个 await client.PostAsJsonAsync 方法。看起来它然后使用 2 个线程慢慢地检查任务,所以到最后我的任务已经等待了 9 或 10 分钟。

这是我想要的行为:

我想创建 1,200 个任务,然后在线程可用时一次运行 3-4 个。我不想立即排队 1,200 个 HTTP 调用。

有什么好的方法可以做到这一点吗?

最佳答案

正如我一直建议的那样...您需要的是 TPL Dataflow(安装:Install-Package System.Threading.Tasks.Dataflow)。

您创建一个 ActionBlock,其中包含要对每个项目执行的操作。设置 MaxDegreeOfParallelism 以进行节流。开始向其中发布并等待其完成:

var block = new ActionBlock<QueryAvailabilityMultidayRequest>(async service => 
{
var availabilityResponse = await client.QueryAvailability(service);
// ...
},
new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 4 });

foreach (var service in RunData.Demand)
{
block.Post(service);
}

block.Complete();
await block.Completion;

关于c# - 如何正确排队要在 C# 中运行的任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33928122/

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