HttpClient 重用会导致 .net 中不同生命周期的问题

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

我遇到了一个问题,但还没有找到答案。

简而言之,我们制作了一个类型化的

HttpClient
并将其注入到单例服务中。一切似乎都很顺利。

现在我们在内部调用此服务

BackgroundService
并且那里有 10 个并行调用
_testService.GetData();
- 前 10 个工作正常,接下来的请求已经卡住并超时。生命周期的某些东西似乎不对。

当客户端第二次被重用时,问题就出现了。客户端似乎是暂时的,但服务现在将是单例的

services.AddHttpClient<ITestClient, TestClient>(client =>
    {
        client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    
    // base address
});
    
public class TestService : ITestService
{
    private readonly ITestClient _client;
    private readonly ISettings _settings;
    private readonly ILogger _logger;

    public NrdClient(
        ITestClient client,
        ISettings settings,
        ILogger logger)
    {
        ArgumentNullException.ThrowIfNull(client);
        _client = client;

        ArgumentNullException.ThrowIfNull(settings);
        _settings = settings;

        ArgumentNullException.ThrowIfNull(logger);
        _logger = logger;
    }

    public async Task<Dto> GetData()
    {
        try
        {
            var content = new StringContent(postData, Encoding.UTF8, "application/x-www-form-urlencoded");

            var response = await _client.PostAsync<T>(url, content);

            return response;
        }
        catch (Exception ex)
        {
            throw;
        }
    }
}

public class TestClient : ITestClient
{
    private readonly HttpClient _client;

    public TestClient()
    {
    }

    public TestClient(HttpClient httpClient, ISettings settings)
    {
        ArgumentNullException.ThrowIfNull(httpClient);
        ArgumentNullException.ThrowIfNull(settings);

        _client = httpClient;
        _client.Timeout = new TimeSpan(0, 0, 10);
    }
    
    public async virtual Task<T> PostAsync<T>(string requestUrl, HttpContent content)
    {
        var response = await _client.PostAsync(requestUrl, content);

        using var stream = await response.Content.ReadAsStreamAsync();
        using GZipStream decompressed = new(stream, CompressionMode.Decompress);
        using StreamReader reader = new(decompressed);
        using JsonTextReader jsonTextReader = new(reader);

        return new JsonSerializer().Deserialize<T>(jsonTextReader);
    }
}
c# asp.net-core .net-core httpclient
1个回答
0
投票

如果您的客户端作为瞬态注入到单例类实例中,它实际上会成为单例本身,这也可能导致一些问题,这里有很好的描述:https://learn.microsoft.com/en-us/ dotnet/fundamentals/networking/http/httpclient-guidelines#dns-behavior

我认为根据 Microsoft 的说法,您应该使用以下内容: https://learn.microsoft.com/en-us/dotnet/fundamentals/networking/http/httpclient-guidelines#pooled-connections

好的做法是为您的

BaseAddress
设置
Httpclient
,这可能也适用于您的用例。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.