如何在 .NET Core 中限制并发 HTTP 请求并处理超时?

问题描述 投票:0回答:1

我正在开发一个 .NET Core 应用程序,我需要并行发出一堆 HTTP 请求。棘手的部分是,请求数量可能会有很大差异,具体取决于用户输入,有时只有 5 个,有时可能最多 50 个。

现在,我正在使用 Task.WhenAll 来处理它们,如下所示:

var tasks = urls.Select(url => httpClient.GetStringAsync(url)).ToArray();
var results = await Task.WhenAll(tasks);

这对于少量请求来说效果很好,但我担心当同时请求太多时应用程序会不堪重负。我还想确保如果一个请求超时或失败,其他请求仍然可以正常完成。

我想知道一些事情:

有没有办法限制同时运行的请求数量,比如一次 10 个?

如果其中一个请求花费的时间太长,我如何确保它超时而不影响其他请求?

重试失败的请求是个好主意,还是有更好的方法来处理?

我不确定 Task.WhenAll 是否是处理此问题的最佳方法,或者是否有更好的模式我应该考虑。任何建议都会很棒!

.net-core async-await concurrency httpclient
1个回答
0
投票

可能有很多方法可以做到这一点(PLINQ、带有 BulkHead 模式的 Polly,...)。与您的示例代码匹配的简单方法只需使用

SemaphoreSlim

var tasks = urls.Select(url => httpClient.GetStringAsync(url)).ToArray();
var results = await Task.WhenAll(tasks);

var semaphore = new SemaphoreSlim(5);
var tasks = urls.Select(async url =>
{
    await semaphore.WaitAsync();
    try
    {
        return await httpClient.GetStringAsync(url);
    }
    finally
    {
        semaphore.Release();
    }
}).ToArray();

var results = await Task.WhenAll(tasks);

根据您的需求,您可能还应该考虑处理超时(提示:

CancellationTokenSource
)和重试失败的请求(Polly 库)

© www.soinside.com 2019 - 2024. All rights reserved.