这就是我正在尝试的:
public static async Task<HttpResponseMessage> post(string specificUrl, string token, StringContent inputData) // specificUrl like "user/" at the end "/"
{
var policy = Policy
.Handle<Exception>()
.OrResult<HttpResponseMessage>(res => !res.IsSuccessStatusCode)
.RetryAsync(3);
string fullUrl = baseUrl + specificUrl;
using (var requestMessage = new HttpRequestMessage(HttpMethod.Post, fullUrl))
{
requestMessage.Content = inputData;
requestMessage.Headers.Add("access_token", token);
//HttpResponseMessage res = await client.SendAsync(requestMessage).ConfigureAwait(false);
HttpResponseMessage res = await policy.ExecuteAsync(() => client.SendAsync(requestMessage)).ConfigureAwait(false);
return res;
}
}
Run Code Online (Sandbox Code Playgroud)
一旦代码到达 waitAndRetryPolicy 并等待所需的时间,我就会收到以下错误:
System.InvalidOperationException:'请求消息已发送。无法多次发送相同的请求消息。
简而言之,您不能重用HttpRequestMessage. 它解决了一大堆无法在级别上缓解的问题(例如流媒体内容等)SendAsync。
您需要HttpRequestMessage在ExecuteAsynclambda 中创建或重新创建,或者更好的是,使用IHttpClientFactory然后在该级别使用Polly 。HttpClientBuilder
重新创建的示例HttpRequestMessage:
return await policy.ExecuteAsync(() =>
{
// Note the 'using' here is a superfluous, but good practice
using var requestMessage = new HttpRequestMessage(HttpMethod.Post, fullUrl)
{
Content = new StringContent(aString)
};
requestMessage.Headers.Add("access_token", token);
return client.SendAsync(requestMessage);
}).ConfigureAwait(false);
Run Code Online (Sandbox Code Playgroud)
但是,理想情况下,您应该HttpClientFactory与类型化或命名的客户端一起使用。
给定一个类型化的客户端
public class MyTypedClient
{
private readonly HttpClient _client;
public MyTypedClient(HttpClient client) => _client = client;
public async Task<HttpResponseMessage> MyCall(string inputData)
{
using var requestMessage = new HttpRequestMessage(HttpMethod.Post, "/someRoute") { Content = new StringContent(inputData) };
var result = await _client.SendAsync(requestMessage);
result.EnsureSuccessStatusCode();
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
依赖注入(DI) 用法示例
private static readonly AsyncRetryPolicy<HttpResponseMessage> retryPolicy
= HttpPolicyExtensions
.HandleTransientHttpError() // Whatever??
.RetryAsync(3);
public static void Main()
{
var serviceCollection = new ServiceCollection();
serviceCollection
.AddHttpClient<MyTypedClient>(ClientConfiguration)
.AddPolicyHandler(retryPolicy);
var provider = serviceCollection.BuildServiceProvider();
// Whatever
}
private static void ClientConfiguration(HttpClient client)
{
client.BaseAddress = new Uri("http://bob.com");
/// blah blah blah
}
Run Code Online (Sandbox Code Playgroud)
注意:这并不是关于依赖注入(DI)、Polly 或其他任何内容(例如世界最佳实践、如何在该级别使用身份验证AddHttpClient等)的教程。这只是一个示例用例,说明它如何适合共同利用政策
掘金队
其他资源