HttpClient 耗时太长

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

我创建了一个 .Net Framework 4.7.2 控制台应用程序,该应用程序在 AWS 托管的 API 中同时发出许多请求。我的问题是请求花费的时间太长。

根据 AWS 控制台中的 taget 组监控,API 的响应时间通常为 100ms-400ms,但在我的应用程序中,每个请求所花费的时间从 1 秒开始,一直增加到 11 秒。

我已经意识到 HttpClient 无法正确关闭连接,因此我们不应该使用

using
,而应始终为每个应用程序使用一个实例。

我已经找到了一个类似的问题,但答案没有解决它。

当我将 MaxDegreeOfParallelism 设置为 1 时,应用程序中的响应时间与应用程序类似。这似乎是在多线程中的 HttpClient 中发生的问题。

这就是我提出请求的方式:

public static class RequestMaker
{
    private static readonly string _urlHttp = "http://apidomain.com/api/apiname";
    private static readonly HttpClient _httpClient = new HttpClient();
    public static async Task<string> PostAsync(string postData)
    {
        bool IsSuccessStatusCode = false;
        int maxRetries = 5;
        int count = 0;
        do
        {
            try
            {
                Stopwatch watcher = Stopwatch.StartNew();
                using (HttpContent content = new StringContent(postData, Encoding.UTF8, "application/json"))
                using (HttpResponseMessage result = await _httpClient.PostAsync(_urlHttp, content).ConfigureAwait(false))
                {
                    watcher.Stop();
                    Console.WriteLine("Elapsed = " + watcher.ElapsedMilliseconds.ToString("N0"));
                    IsSuccessStatusCode = result.IsSuccessStatusCode;
                    if (IsSuccessStatusCode)
                        return await result.Content.ReadAsStringAsync().ConfigureAwait(false);

                    count++;
                    if (count > maxRetries)
                        return "";

                    Console.WriteLine($"Retrying request because of request status code {result.StatusCode}");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                count++;
                if (count > maxRetries)
                    return "";
            }
        } while (!IsSuccessStatusCode);

        return "";
    }
}

这是我同时调用请求的函数:

static void RunBatchMany(List<string> list)
{
    var getCustomerBlock = new TransformBlock<string, long>(
        async lstRec =>
        {
            ApiInputObject apiInput = new ApiInputObject();
            
            // PrepareInputObject
            string postData = JsonConvert.SerializeObject(apiInput);

            Stopwatch watcher = Stopwatch.StartNew();
            string json = await RequestMaker.PostAsync(postData);
            ApiResponseObject res = JsonConvert.DeserializeObject<ApiResponseObject>(json);
            watcher.Stop();
            return watcher.ElapsedMilliseconds;

        }, new ExecutionDataflowBlockOptions
        {
            MaxDegreeOfParallelism = 8
        });

    foreach (var id in list)
        getCustomerBlock.Post(id);

    getCustomerBlock.Complete();
    getCustomerBlock.Completion.Wait();
}
c# concurrency dotnet-httpclient tpl-dataflow .net-4.7.2
1个回答
0
投票

您可以尝试使用此扩展禁用查找 ipv6

public static void DisableIpV6(this SocketsHttpHandler socketsHttpHandler)
{
    socketsHttpHandler.ConnectCallback = async (context, cancellationToken) =>
    {
        Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        await socket.ConnectAsync(context.DnsEndPoint.Host, context.DnsEndPoint.Port);
        return new NetworkStream(socket, true);
    };
}
using SocketsHttpHandler handler = new();
handler.DisableIpV6();
using Httpclient httpclient = new(handler,false);

来源

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