HttpClient 和 Polly 延迟 14 秒
14s delay with HttpClient and Polly
我正在使用 httpClient 执行 POST 请求。我正在使用 Polly 进行重试。发生的事情是第一次尝试需要 14 秒,即使我指定了 2 秒的重试时间。第一次尝试在 14 秒后失败,然后有 2 秒的间隔,直到第二次尝试。我希望它每 2 秒尝试一次,超时并重试任何错误。这是正确的做法吗?
var retryPolicy = Policy
.Handle<Exception>() // retry on any
.WaitAndRetryAsync(6,
retryAttempt => TimeSpan.FromMilliseconds(2000),
(response, calculatedWaitDuration, ctx) =>
{
Log.LogError($"Failed attempt {attempt++}. Waited for {calculatedWaitDuration}. Exception: {response?.ToString()}");
});
HttpResponseMessage httpResp = null;
await retryPolicy.ExecuteAsync(async () =>
{
httpResp = await DoPost();
httpResp?.EnsureSuccessStatusCode(); // throws HttpRequestException
return httpResp;
});
var respBody = await httpResp.Content.ReadAsStringAsync();
return respBody;
async Task<HttpResponseMessage> DoPost()
{
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = new StringContent(json, Encoding.UTF8, Constants.JsonContentType),
Headers = { Authorization = await GetAuthenticationTokenAsync() }
};
ServicePointManager.Expect100Continue = false;
var httpResponseMessage = await StaticHttpClient.SendAsync(httpRequestMessage).ConfigureAwait(false);
return httpResponseMessage;
}
The first attempt takes 14s even though I specified a retry time of 2s.
The first attempt fails after 14s, then there is a 2s gap until the second attempt.
没错。 WaitAndRetry 是关于失败后等待多长时间,然后再重试,如 specified in the documentation.
What I want it to try every 2s and timeout and retry on any error.
要强制超时,请使用 Polly 的 Timeout policy. To both impose a timeout and retry, combine both Timeout and Retry policies using PolicyWrap。因此,您可以像这样调整您的代码:
var timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(2000));
var retryPolicy = Policy
.Handle<Exception>() // retry on any
.WaitAndRetryAsync(6, // or just RetryAsync() if you don't want any wait before retrying
retryAttempt => /* a timespan, _if you want a wait before retrying */,
(response, calculatedWaitDuration, ctx) =>
{
Log.LogError($"Failed attempt {attempt++}. Waited for {calculatedWaitDuration}. Exception: {response?.ToString()}");
});
var combinedPolicy = retryPolicy.WrapAsync(timeoutPolicy);
HttpResponseMessage httpResp = null;
await combinedPolicy.ExecuteAsync(async () =>
{
httpResp = await DoPost();
httpResp?.EnsureSuccessStatusCode(); // throws HttpRequestException
return httpResp;
});
有关更多讨论和示例,请参阅 。
我正在使用 httpClient 执行 POST 请求。我正在使用 Polly 进行重试。发生的事情是第一次尝试需要 14 秒,即使我指定了 2 秒的重试时间。第一次尝试在 14 秒后失败,然后有 2 秒的间隔,直到第二次尝试。我希望它每 2 秒尝试一次,超时并重试任何错误。这是正确的做法吗?
var retryPolicy = Policy
.Handle<Exception>() // retry on any
.WaitAndRetryAsync(6,
retryAttempt => TimeSpan.FromMilliseconds(2000),
(response, calculatedWaitDuration, ctx) =>
{
Log.LogError($"Failed attempt {attempt++}. Waited for {calculatedWaitDuration}. Exception: {response?.ToString()}");
});
HttpResponseMessage httpResp = null;
await retryPolicy.ExecuteAsync(async () =>
{
httpResp = await DoPost();
httpResp?.EnsureSuccessStatusCode(); // throws HttpRequestException
return httpResp;
});
var respBody = await httpResp.Content.ReadAsStringAsync();
return respBody;
async Task<HttpResponseMessage> DoPost()
{
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = new StringContent(json, Encoding.UTF8, Constants.JsonContentType),
Headers = { Authorization = await GetAuthenticationTokenAsync() }
};
ServicePointManager.Expect100Continue = false;
var httpResponseMessage = await StaticHttpClient.SendAsync(httpRequestMessage).ConfigureAwait(false);
return httpResponseMessage;
}
The first attempt takes 14s even though I specified a retry time of 2s. The first attempt fails after 14s, then there is a 2s gap until the second attempt.
没错。 WaitAndRetry 是关于失败后等待多长时间,然后再重试,如 specified in the documentation.
What I want it to try every 2s and timeout and retry on any error.
要强制超时,请使用 Polly 的 Timeout policy. To both impose a timeout and retry, combine both Timeout and Retry policies using PolicyWrap。因此,您可以像这样调整您的代码:
var timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(2000));
var retryPolicy = Policy
.Handle<Exception>() // retry on any
.WaitAndRetryAsync(6, // or just RetryAsync() if you don't want any wait before retrying
retryAttempt => /* a timespan, _if you want a wait before retrying */,
(response, calculatedWaitDuration, ctx) =>
{
Log.LogError($"Failed attempt {attempt++}. Waited for {calculatedWaitDuration}. Exception: {response?.ToString()}");
});
var combinedPolicy = retryPolicy.WrapAsync(timeoutPolicy);
HttpResponseMessage httpResp = null;
await combinedPolicy.ExecuteAsync(async () =>
{
httpResp = await DoPost();
httpResp?.EnsureSuccessStatusCode(); // throws HttpRequestException
return httpResp;
});
有关更多讨论和示例,请参阅