參考資料:https://www.cnblogs.com/edisonchou/p/9159644.html
特征:可以實現一些代碼的熔斷和降級
代碼:
////普通,其中 Fallback相當於降級處理 //Policy.Handle<ArgumentException>().Fallback(()=>{ // MessageBox.Show("Error occured"); //}).Execute(()=> { // MessageBox.Show("Job Start"); // throw new ArgumentException("Hello Polly!"); // MessageBox.Show("Job End"); //}); ////重試 3次重試后結束 //Policy.Handle<ArgumentException>().Retry(3).Execute(() => { // MessageBox.Show("Job retry Start"); // throw new ArgumentException("Hello retry Polly!"); // MessageBox.Show("Job retry End"); //}); ////熔斷 重試3次后再次失敗以后十秒一次調用 //var policy = Policy.Handle<Exception>().CircuitBreaker(3, TimeSpan.FromSeconds(10)); //while (true) //{ // try // { // policy.Execute(() => // { // Console.WriteLine("Job Start"); // throw new Exception("Special error occured"); // Console.WriteLine("Job End"); // }); // } // catch (Exception ex) // { // Console.WriteLine("There's one unhandled exception : " + ex.Message); // } // Thread.Sleep(500); //} ////這里涉及到Polly中關於超時的兩個策略:一個是悲觀策略(Pessimistic),一個是樂觀策略(Optimistic)。其中,悲觀策略超時后會直接拋異常,而樂觀策略則不會 //// Wrap是指策略封裝,可以把多個ISyncPolicy合並到一起執行。Timeout則是指超時處理,但是超時策略一般不能直接使用,而是其其他策略封裝到一起使用。 ////thread.sleep這個超時沒有用走Fallback方法,但是再excute里面執行一個方法出異常的時候會走fallback方法 //try //{ // var policyExp = Policy.Handle<Exception>().Fallback(() => // { // Console.WriteLine("Fallback"); // }); // var policyTimtout = Policy.Timeout(3, TimeoutStrategy.Pessimistic); // var mainPolicy = Policy.Wrap(policyTimtout, policyExp); // mainPolicy.Execute(() => // { // Console.WriteLine("Job Start..."); // Thread.Sleep(5000); // //throw new Exception("error"); // Console.WriteLine("Job End..."); // }); //} //catch (Exception ex) //{ // Console.WriteLine($"Unhandled exception : {ex.GetType()} : {ex.Message}"); //} ////一些高級方法 :WaitAndRetryAsync,等待異步完成,並且重試指定次數 ExecuteAndCaptureAsync,執行並且返回一個自己方法需要返回的類型,可以在這里查看更多 https://github.com/App-vNext/Polly var policy = Policy<byte[]>.Handle<Exception>() .FallbackAsync(async c => { //熔斷后再來個通知 Console.WriteLine("熔斷完成,通知一下"); return new byte[0]; }, async r => { try { //這里如果拋出錯誤不用catch捕捉的話,就不會走到通知的方法。 throw new Exception("error"); //先來個降級熔斷。 Console.WriteLine("我降級熔斷了"); } catch (Exception ex) { Console.WriteLine("熔斷異常"); } }); try { //設置一個超時時間,里面加個回調函數給個提示 var pTimeout = Policy.TimeoutAsync(20, TimeoutStrategy.Pessimistic, async (context, timespan, task) => { Console.WriteLine("Timeout!"); }); var excPolicy = policy.WrapAsync(pTimeout); var bytes = await excPolicy.ExecuteAsync(async () => { Console.WriteLine("start Job"); //throw new Exception("error"); HttpClient httpClient = new HttpClient(); var result = await httpClient.GetByteArrayAsync("https://images2018.cnblogs.com/blog/381412/201806/381412-20180606230929894-145212290.png"); Console.WriteLine("Finish Job"); return result; }); Console.WriteLine($"Length of bytes : {bytes.Length}"); } catch (Exception ex) { //這里如果熔斷的方法拋出異常的時候,可以從這里捕捉主方法的執行異常,如果熔斷方法沒有異常的情況下,主方法報錯也不會走到這個地方的 Console.WriteLine($"Unhandled exception : {ex.GetType()} : {ex.Message}"); }
