如何使以下 Polly Retry 策略讓用戶指定自定義處理程式,如下面的:
.Handle<WebSocketException>(exception => IsWebSocketErrorRetryEligible(exception))
片段
public static async Task DoAsync(Func<Task> action, TimeSpan retryInterval, int retryCount = 3)
{
await DoAsync<object?>(async () =>
{
await action();
return null;
}, retryInterval, retryCount);
}
public static async Task<T> DoAsync<T>(Func<Task<T>> action, TimeSpan retryWait, int retryCount = 0)
{
var policyResult = await Policy
.Handle<Exception>()
.WaitAndRetryAsync(retryCount, retryAttempt => retryWait)
.ExecuteAndCaptureAsync(action);
if (policyResult.Outcome == OutcomeType.Failure)
{
throw policyResult.FinalException;
}
return policyResult.Result;
}
private bool IsWebSocketErrorRetryEligible(WebSocketException wex)
{
if (wex.InnerException is HttpRequestException)
{
// assume transient failure
return true;
}
return wex.WebSocketErrorCode switch
{
WebSocketError.ConnectionClosedPrematurely => true, // maybe a network blip?
WebSocketError.Faulted => true, // maybe a server error or cosmic radiation?
WebSocketError.HeaderError => true, // maybe a transient server error?
WebSocketError.InvalidMessageType => false,
WebSocketError.InvalidState => false,
WebSocketError.NativeError => true, // maybe a transient server error?
WebSocketError.NotAWebSocket => Regex.IsMatch(wex.Message, "\\b(5\\d\\d|408)\\b"), // 5xx errors timeouts
WebSocketError.Success => true, // should never happen, but try again
WebSocketError.UnsupportedProtocol => false,
WebSocketError.UnsupportedVersion => false,
_ => throw new ArgumentOutOfRangeException(nameof(wex))
};
}
uj5u.com熱心網友回復:
如果您想允許您的DoAsync方法的使用者為重試策略定義一個自定義謂詞,那么您可以這樣做:
public static async Task<T> DoAsync<T, TEx>(Func<Task<T>> action, TimeSpan retryWait, int retryCount = 0, Func<TEx, bool> exceptionFilter) where TEx: Exception
{
var policyResult = await Policy
.Handle<TEx>(exceptionFilter)
.WaitAndRetryAsync(retryCount, retryAttempt => retryWait)
.ExecuteAndCaptureAsync(action);
if (policyResult.Outcome == OutcomeType.Failure)
{
throw policyResult.FinalException;
}
return policyResult.Result;
}
- 添加
TEx為新的泛型型別引數并將其約束為Exception - 為方法添加了一個新
Func<TEx, bool>引數 - 將您的全部例外觸發器 (
.Handle<Exception>()) 替換為用戶提供的觸發器
注意#1
如果您需要允許您的消費者定義任意數量的例外過濾器,則不能使用此技術,因為它TEx是簽名的一部分。
筆記2
無需使用ExecuteAndCaptureAsync然后基于 分支,Outcome因為您只是重新實作了ExecuteAsync作業原理。
public static async Task<T> DoAsync<T, TEx>(Func<Task<T>> action, TimeSpan retryWait, int retryCount = 0, Func<TEx, bool> exceptionFilter) where TEx: Exception
=> await Policy
.Handle<TEx>(exceptionFilter)
.WaitAndRetryAsync(retryCount, retryAttempt => retryWait)
.ExecuteAsync(action);
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/514882.html
標籤:C#。网波莉重试逻辑
