如何使用 Polly 通过取消令牌进行重试?

How can I use Polly for retries with a cancellation token?

我是 Polly 的新手,所以与我正在尝试的方法相比,可能有一种完全不同的方法,那完全没问题。

我的目标是:

  1. token可能因超时或请求取消
  2. 永远重试,直到成功或 token 被取消。
  3. 请求取消等待时应立即退出

尽管我使用的方法似乎遗漏了一些东西,但可能有 better/cleaner 方法可以完成我想要的。我特别想到这一行.WaitAndRetryForever(retryAttempt => TimeSpan.Zero,。我觉得我应该能够在这里传递 retryDelay 而不是 TimeSpan.Zero 但是如果我在请求取消时这样做,它不会 return 直到 retryDelay 完成等待而不是像我想要的那样立即。

我确实看到 .Execute 看起来可以用取消令牌做一些事情,但我不知道如何使用它,所以如果这是我的答案,请忽略我的其他废话。

以防万一 Polly NuGet 开发人员看到这一点,我希望看到的是 WaitAndRetryForever 的重载,它将取消令牌作为参数,以便它可以 return 立即被取消。我不太愿意将其作为官方建议,因为我对 Polly 还很陌生,我不确定这是否有意义。

这是我目前使用的方法:

internal static void Retry(Action action, TimeSpan retryDelay, CancellationToken token)
{
    try
    {
        Policy
            .Handle<IOException>()
            .WaitAndRetryForever(retryAttempt => TimeSpan.Zero,
                (ex, delay, context) =>
                {
                    Task.Delay(retryDelay, token).GetAwaiter().GetResult();
                    token.ThrowIfCancellationRequested();
                    //Log exception here
                })
            .Execute(() =>
            {
                token.ThrowIfCancellationRequested();
                action.Invoke();
            });
    }
    catch (OperationCanceledException)
    {
        //Log cancellation here
        throw;
    }
    catch (Exception ex)
    {
        //Log exception here
        throw;
    }
}

Execute 的重载需要 CancellationToken:

.Execute((ct) =>
{
    ct.ThrowIfCancellationRequested();
    action.Invoke();
}, token);

此令牌也将应用于 WaitAndRetryForever 内处理的延迟。

Try it online