2016-12-15 56 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