One, background
When first contact Polly was doing a micro-service system, then only use a single timeout policy and retry strategy, more advanced features will no longer be studied. Recently opened to the development of a client PC side of the PC, when there is a customer demand, after 5 seconds to initiate the request if no response is retried, a total of three times can be retried, if none of the returned data request three times, it is regarded as a request fails.
About Polly advanced usage can refer to the official Wiki document can be domestic, there are many excellent introductory article, such as this and this .
Second, the idea
After a review of official documents Polly, Polly found to provide a strategy combination function, each Policy instance can call its Wrap()
methods combined with another strategy.
Or by Policy
a static class provides Warp()
two static methods to specify policies required combination.
According to the needs described, we need to use timeouts and retries policy strategy, as long as it can be combined. It should be noted however, a pit that their combined order.
The right combination order should be retried strategy .Warp (timeout policy) , rather than the timeout policy .Warp (retry strategy) . This is because after the timeout Polly throws TimeoutRejectedException
after an exception, in the retry strategy to capture the exception, will begin to retry the operation, that is a combination of strategy behind the ExecuteAsync()
method of receiving the commission.
Third, to achieve
First, we define a method for combining strategies (time-out and retry), because here I was commissioned by the incoming asynchronous operation, it returns AsyncPolicy
an object.
private AsyncPolicyWrap BuildTimeoutRetryPolicy(string msg)
{
// 超时策略,执行目标委托超过 5 秒则视为超时,抛出异常。
var timeoutPolicy = Policy.TimeoutAsync(5);
// 重试策略,重试 2 次,每次打印信息。
var retryPolicy = Policy.Handle<TimeoutRejectedException>().RetryAsync(2, (exception, i) =>
{
Console.WriteLine("开始第 i 次重试...");
});
return retryPolicy.WrapAsync(timeoutPolicy);
}
After defining a good strategy, it is our practical use. Here to explain the implementation of logic, when the first request if a timeout occurs, then enter the retry strategy retry twice, the last time when still throws TimeoutRejectedException
an exception, the retry strategy is no longer capture directly to the abnormal thrown to the caller.
private async Task<string> GetResult(AsyncPolicyWrap policy)
{
try
{
return await policy.ExecuteAsync(() => SendDataAsync(sendProtocol));
}
catch (TimeoutRejectedException)
{
return "超时";
}
}