c# - 多个HTTP请求触发HTTP Client超时

标签 c# asp.net-core .net-core azure-functions httpclient

我有一个应用程序异步发送 500 个 HTTP 请求。由于 HTTP 客户端超时,15 秒后处理的所有请求都会失败,即使请求的端点已返回 200 OK,也是如此。

代码非常简单。这里我们获取一大块请求(500),并异步执行它们。应该注意的是,下面的函数是在基于消耗的计划上运行的 Azure 函数。

    public async Task RunBatch(List<Request> requests)
    {
        if (requests != null && requests .Count > 0)
        {
            var tasks = new Task[requests.Count];
            var i = 0;
            foreach (var request in requests)
            {
                var request = new HttpRequestMessage(HttpMethod.Post, new Uri(request.Url));
                request.Content = new StringContent(request.BodyString, Encoding.UTF8, "application/json");
                tasks[i] = _httpClient.SendAsync(request);
                i++;
            }

            await Task.WhenAll(tasks);
        }
    }

我的构造函数中存在以下代码

_httpClient = new HttpClient();
_httpClient.Timeout = new TimeSpan(0, 0, 15); // 15 seconds

以下是来自 Azure 的日志。

enter image description here enter image description here

我希望每个请求的超时时间为 15 秒。但是,每当我的服务器开始处理等待的请求时,我都需要它给我一个准确的响应代码。这可能吗?

我应该注意:使用较高的 Http 超时(1 分钟),所有请求都会成功。

最佳答案

就我个人而言,我认为尝试发出 500 个并发请求总是容易出错。您提到您正在异步执行此操作,但实际上,当您启动 500 个“热门”任务然后等待它们全部完成时,您的代码中并没有太多异步。

我会使用信号量来控制一次可以发出多少个请求。您可能需要玩弄数字才能找到最佳位置。

以下代码在 LINQPad 中运行良好(尽管 bing 很快注意到奇数个请求并开始向页面添加验证码):

// using System.Threading;
async Task Main()
{
    var httpClient = new HttpClient();
    var urls = Enumerable.Range(1, 500).Select(e => "https://www.bing.com/").ToList();
    
    // 10 concurrent requests - tweak this number
    var semaphore = new SemaphoreSlim(10, 10);
    
    var tasks = urls.Select(u => MakeRequest(u, semaphore, httpClient));
        
    var allResponses = await Task.WhenAll(tasks);
    
    // Do something with allResponses
}

private async Task<string> MakeRequest(string url, SemaphoreSlim semaphore, HttpClient httpClient)
{
    try
    {
        await semaphore.WaitAsync();
        var request = new HttpRequestMessage(HttpMethod.Get, new Uri(url));
        var response = await httpClient.SendAsync(request);
        
        // Add an optional delay for further throttling:
        //await Task.Delay(TimeSpan.FromMilliseconds(100));
        
        return await response.Content.ReadAsStringAsync();
    }
    finally
    {
        semaphore.Release();
    }
}

关于c# - 多个HTTP请求触发HTTP Client超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60013771/

相关文章:

.net-core - '{{FSharpCoreShippedPackageVersion}}' 不是有效的版本字符串

c# - 在应用程序和 IFrame 之间传递凭据

asp.net-core - 在 Asp.Net Core 中注入(inject) DbContext。具体类型还是接口(interface)?

asp.net-core - 在 Blazor 中更改绑定(bind)到组件的模型时更新 UI

c# - 如何从 ASP.NET Core 中的 .json 文件读取 AppSettings 值

linux - 如何在 Linux 中运行 asp dot net core 图像?

c# - 使用MySqlDataReader时遇到 fatal error

c# - 如何构造一个正确的MySQL连接串?

c# - Ninject 默认上下文绑定(bind)

c# - 使用 IStringLocalizer 对数据注释进行本地化