問題描述:某些場景下,需要對產生異常的任務或沒有達到預期結果的任務進行重試,若重試次數達到了我們設定的閾值,則再放棄任務
簡單方法:
public static void Operat(int count = 3) { //循環重試次數 for (int i = 0; i < count; i++) { try { //執行目標方法,若無異常,則結束循環,返回 SomeFunctionThatCanFail(); break; } catch (Exception ex) { //若發生了異常,則打印日志,休眠5秒鍾之后繼續重試 Console.WriteLine($"異常!{i}"); Thread.Sleep(5000); } } }
方案一
使用一個靜態的泛型方法來處理,創建通用的任務重試機制,我們可以使用action作為參數,如下:
public class Program { static void Main(string[] args) { DoAction<bool>(()=>SomeFunctionThatCanFail(), TimeSpan.FromSeconds(1), 2); Console.Read(); } public static bool SomeFunctionThatCanFail() { Console.WriteLine("方法"); Convert.ToInt32("nihao"); return false; } public static void DoAction<T>(Func<T> action, TimeSpan retryInterval, int maxAttempCount = 3) { var exceptions = new List<Exception>(); for (int i = 0; i < maxAttempCount; i++) { try { var result = action(); if (i > 0) Thread.Sleep(i); } catch (Exception ex) { exceptions.Add(ex); } } } }
方案二
使用第三方組件,eg:Polly,Polly是一個任務重試解決方案組件,用Polly你可以非常方便地完成如:Retry,Retry Forever,Wait and Retry或者Circuit Breaker等等重試操作,並且Polly的重試寫法是鏈式的,如:

方案三
以下方法可以在重試失敗時補充異常處理方法
public class Program { static void Main(string[] args) { DoAction(()=> SomeFunctionThatCanFail(), ()=> Log(),3); Console.Read(); } public static bool SomeFunctionThatCanFail() { Console.WriteLine("進入任務內容"); Convert.ToInt32("nihao"); return false; } public static void Log() { Console.WriteLine("產生異常!"); } public static void DoAction<T>(Func<T> action,Action OnFailureAction, int maxAttempCount = 3) { var exceptions = new List<Exception>(); for (int i = 0; i < maxAttempCount; i++) { try { var result = action(); if (i > 0) Thread.Sleep(i); } catch (Exception ex) { OnFailureAction(); } } } }
