2016-04-04 16 views
3

一時的なフォールト処理にPollyフレームワークを使用しています。同期動作の場合Polly回路遮断器のポリシーは正常に機能しますが、非同期バージョンを作成しても実行を再試行しません。親切に示唆:PollyフレームワークCircuitBreakerAsyncは、例外が発生した場合に再試行しません。

非同期メソッド

private async static Task HelloWorld() 
    { 
     if (DateTime.Now < programStartTime.AddSeconds(10)) 
     { 
      Console.WriteLine("Task Failed."); 
      throw new TimeoutException(); 
     } 
     await Task.Delay(TimeSpan.FromSeconds(1)); 
     Console.WriteLine("Task Completed."); 
    } 

ポリー回路ブレーカ非同期ポリシー:

AsyncDemo3(HelloWorldの:ポリー回路ブレーカポリシーを実行

private static void AsyncDemo3(Func<Task> action) 
    { 
     programStartTime = DateTime.Now; 

     Policy policy = Policy 
      .Handle<TimeoutException>() 
      .CircuitBreakerAsync(3, TimeSpan.FromSeconds(2)); 
     try 
     { 
      var a = policy.ExecuteAndCaptureAsync(action, true).GetAwaiter().GetResult(); 
     } 
     catch (AggregateException ex) 
     { 
      Console.WriteLine("Exception: " + ex.Message); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("Exception: " + ex.Message); 
     } 
    } 

);

問題の発見と解決に役立ちます。

答えて

7

サーキットブレーカーのポリシーが誤解していると思います。

を指定した回数だけ呼び出すと、そのたびに失敗し、指定されたメソッドの呼び出しが一定時間停止します。しかし、それ自体は再試行しません。

あなたがしたいと思うことをするには、リトライポリシーとサーキットブレーカポリシーを組み合わせる必要があります。それを行う1つの方法は、次のようになります

Policy retryPolicy = Policy.Handle<TimeoutException>().RetryAsync(3); 

Policy circuitBreakerPolicy = Policy 
    .Handle<TimeoutException>() 
    .CircuitBreakerAsync(3, TimeSpan.FromSeconds(2)); 

try 
{ 
    retryPolicy.ExecuteAsync(() => circuitBreakerPolicy.ExecuteAsync(action, true)) 
     .GetAwaiter().GetResult(); 
} 
… 

このコードの出力である:

Task Failed. 
Task Failed. 
Task Failed. 
Exception: The circuit is now open and is not allowing calls. 
+0

ポリーも今[PolicyWrap(https://github.com/App-vNext/Polly添加しました/ wiki/PolicyWrap)、ポリシーをより簡潔に組み合わせるための構文を作ることができます: 'retryPolicy.WrapAsync(circuitBreakerPolicy).ExecuteAsync(...)' –

関連する問題