9

我正在通过以下方式创建重试策略:

var policy = Policy.Handle<Exception>().WaitAndRetryAsync...

如何为上面的重试策略设置超时?Policy.TimeoutAsync返回 a TimeoutPolicy,因此我无法做类似的事情

var policy = Policy.TimeoutAsync(30).Handle<Exception>().WaitAndRetryAsync....

超时是否成为我所有重试策略的通用设置?

4

1 回答 1

24

要组合策略,您需要分别构建每个策略,然后使用PolicyWrap组合它们。

建立一个适用于所有重试作为一个整体(即整个操作)的整体超时:

var overallTimeoutPolicy = Policy.TimeoutAsync(60); 
var waitAndRetryPolicy = Policy
    .Handle<WhateverException>()
    .WaitAndRetryAsync(/* your wait-and-retry specification*/);
var combinedPolicy = overallTimeoutPolicy.WrapAsync(waitAndRetryPolicy);

await combinedPolicy.ExecuteAsync(cancellationToken => ...)

要对每个特定尝试施加超时,请按其他顺序包装重试和超时策略:

var timeoutPerTry = Policy.TimeoutAsync(10); 
var waitAndRetryPolicy = Policy
    .Handle<WhateverException>()
    .WaitAndRetryAsync(/* your wait-and-retry specification*/);
var combinedPolicy = waitAndRetryPolicy.WrapAsync(timeoutPerTry);

await combinedPolicy.ExecuteAsync(cancellationToken => ...);

甚至使用两种超时(每次尝试,每次整体操作):

var overallTimeout = Policy.TimeoutAsync(60); 
var timeoutPerTry = Policy.TimeoutAsync(10); 
var waitAndRetryPolicy = Policy
    .Handle<WhateverException>()
    .WaitAndRetryAsync(/* your wait-and-retry specification*/);

var combinedPolicy = Policy
    .WrapAsync(overallTimeout, waitAndRetryPolicy, timeoutPerTry); // demonstrates alternative PolicyWrap syntax

await combinedPolicy.ExecuteAsync(cancellationToken => ...);

PolicyWrap wiki提供了完整的语法细节,以及在 wrap 中组合策略时不同排序效果的建议


回答:

超时是否成为我所有重试策略的通用设置?

策略适用于您使用它们的任何地方(无论是单独使用,还是作为 的一部分PolicyWrap)。

您可以线程安全地TimeoutPolicy使用您在多个呼叫站点配置的任何实例。因此,要将超时应用为所有重试策略的通用设置,只需在每个呼叫站点中包含相同TimeoutPolicy的实例。如果需要,可以使用不同的重试策略实例安全地包装PolicyWrap单个实例。TimeoutPolicy

如果您的等待和重试规范和超时规范对于所有呼叫站点都是通用的,只需创建一个PolicyWrap包含两者的实例(根据上面的代码示例),然后在任何地方重复使用该PolicyWrap实例。再次 - 线程安全。

于 2017-04-04T11:08:36.133 回答