首页 > 解决方案 > polly 中的 HttpClient 使用

问题描述

想要验证是否HttpCLient应该在传递给 polly for 的方法之外创建实例ExecuteAsync,或者在其中创建实例?

我目前的使用在两个选项之间有所不同,我不确定哪个是正确的?

此外,如果它引起一些缺点,或者可能的内存泄漏等?

得到:

var client = new HttpClient(new NativeMessageHandler()) { Timeout = new TimeSpan(0, 0, TimeOutSec) };

var httpResponse = await AuthenticationOnUnauthorizePolicy.ExecuteAsync(async () =>
{
    UpdateClientHeader(client, correlationId);
    return await client.GetAsync(url, token);
});

邮政:

var httpResponse = await AuthenticationOnUnauthorizePolicy.ExecuteAsync(async () =>
{
    using (var client = new HttpClient(new NativeMessageHandler()) { Timeout = new TimeSpan(0, 0, TimeOutSec) })
    {
        UpdateClientHeader(client, correlationId);
        WriteNetworkAccessStatusToLog();
        return await client.PostAsync(url, content);
    }
});

这里使用的策略:

AuthenticationOnUnauthorizePolicy = Policy
     .HandleResult<HttpResponseMessage>(reposnse => reposnse.StatusCode == HttpStatusCode.Unauthorized)
     .RetryAsync(1, onRetryAsync:
     async (response, count, context) =>
     {
         _logger.Info("Unauthorized Response! Retrying Authentication...");
         await Authenticate();
     });

感谢对上述代码的任何评论。

有正确的方法吗?

我是否需要再次使用Context来获取客户端,或者我的使用情况还可以吗?


更新:

认证方法:

public virtual async Task Authenticate()
{
    // lock it - only one request can request token
    if (Interlocked.CompareExchange(ref _isAuthenticated, 1, 0) == 0)
    {
        var result = new WebResult();
        var loginModel = new LoginModel
        {
            email = _settingService.Email,
            password = _settingService.Password
        };

        var url = ......
        var correlationId = Guid.NewGuid().ToString();

        try
        {
            var stringObj = JsonHelper.SerializeObject(loginModel);
            HttpContent content = new StringContent(stringObj, Encoding.UTF8, HttpConsts.JsonMediaType);

            using (var client = new HttpClient(new NativeMessageHandler()) { Timeout = new TimeSpan(0, 0, TimeOutSec) }
            )
            {
                UpdateClientHeader(client, correlationId, useToken: false); // not token, we need new one
                using (var httpResponse = await client.PostAsync(url, content))
                {
                    var sReader = await httpResponse.Content.ReadAsStringAsync();
                    await HandleRequest(result, sReader, httpResponse, correlationId, url, "result");
                }
            }
            if (result != null && !result.HasError)
            {
                _loginToken = result.Token;
            }
        }
        catch (Exception ex)
        {
            // Log error
        }
        finally
        {
            _isAuthenticated = 0;
        }
    }
}

更新客户端头方法:

if (_loginToken != null &&
                !client.DefaultRequestHeaders.Contains("Token"))
            {
                client.DefaultRequestHeaders.Add("Token", _loginToken );
            }
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(HttpConsts.JsonMediaType));

标签: c#xamarin.formsdotnet-httpclientpolly

解决方案


推荐阅读