2016-12-15 62 views
2

我正在使用Topaz塊實現對Azure調用的重試處理。我已經實現了一個自定義指數退避重試策略。不過,我不理解這之間的區別:使用瞬態故障處理重試異步操作

var result = await RetryPolicy.ExecuteAsync(async() => await SomeAsyncOperation()); 

VS

var result = await RetryPolicy.ExecuteAsync(() => SomeAsyncOperation()); 

RetryPolicy.ExecuteAsync根據文檔,直到retrypolicy滿意會重複執行異步任務,所以第一解決方案似乎是正確的,因爲它等待異步操作的結果。然而,我已經嘗試了兩種方式,而且他們似乎也有類似的功能。對於第二種情況,我還看到了例子like this onethis one。哪一個是正確的?

+1

它們都是正確的。如果你對更多細節感興趣,可以在我的博客上寫一篇文章(http://blog.stephencleary.com/2016/12/eliding-async-await)。HTML)。 –

回答

3

這是在您的代碼中引入冗餘等待的非常普遍的現象。

例如:總之,我們正在看這樣的事情。

public Task ExecuteAsync(Func<Task> taskAction) 
{ 
     return taskAction(); 
} 

(1) await ExecuteAsync(() => Task.Delay(5000)); 

    vs : 

(2) await ExecuteAsync(async () => await Task.Delay(5000)); 

(1)你正等待你傳遞給重試策略委託創建任務。

(2)你正在等待一個不同的任務,在一個冗餘的一個, 你內心的等你在等待任務等待(1)不同的任務創造了你打電話時等待ExecuteAsync。

它的工作原理是因爲你的代碼行爲相同,它仍然等待ExecuteAsync返回的任務。 它只是通過創建一個額外的任務(沒有很好的理由)來做一些更繁重的工作。

RetryPolicy.cs

ExecuteAsync.cs

這裏的寓意是等待您打算任務。

另外:

有配發的防守多餘的await是在那裏的,但也有一些是至關重要的,看起來他們是多餘的。

例如:

藉此閱讀其中連接不應被設置,直到非同步(用於exmpale I/O)操作完成操作 。

await DoSomeReadingAsync(); 

    public async Task DoSomeReadingAsync() 
    { 
     using(var connection = new Connection()) 
     { 
      await SomeReadOperationAsync(connection); 
     } 
    } 

如果返回的內部任務,而不等待在這裏,它會destorus 因爲做內部異步操作之前連接將被佈置。

await DoSomeReadingAsync(); 

    public Task DoSomeReadingAsync() 
    { 
     using(var connection = new Connection()) 
     { 
      return SomeReadOperationAsync(connection); 
     } 
    } 
+0

詳細解釋。謝謝。 – WildFlower

相關問題