c# - 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));
解决方案
推荐阅读
- python - 如何在两个字符串标记python之间捕获数据
- android - 从 android studio 安装时一切正常,从 playstore 安装时结果相同,但 PDF 的一项活动不起作用
- git - 如何创建子分支?
- apache-kafka - Kafka 无法在 3 个单独的 VM 上创建基本的 3 节点集群
- php - 使用 php 浏览和更新数据库
- java - 如何使用 increment() 增加现有 redis 哈希字段的值?
- kotlin - “运算符重载”中的“重载”只是语义上的吗?
- windows - 权限的 Power Shell 脚本不断覆盖以前的脚本
- javascript - 在 ReactJs 中使用 Fetch 下载图像
- python - 无法解析用户名以确保我已登录网站