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

4

我对Polly很陌生,所以可能会有完全不同的方法来完成我正在尝试做的事情,这是完全可以的。

我的目标是:

  1. token 可能由于超时或请求而被取消
  2. 无限重试,直到成功或取消 token.
  3. 在请求取消时应立即退出等待

虽然我目前使用的方法似乎可行,但我觉得还缺少一些东西,并且可能存在更好/更清晰的方法来完成我想要的事情。 我特别考虑了这一行 .WaitAndRetryForever(retryAttempt => TimeSpan.Zero,。 我觉得我应该能够传递retryDelay而不是TimeSpan.Zero,但如果我这样做,当请求取消时,它不会立即返回而是会等待retryDelay等待完成,这不是我想要的。

我看到.Execute似乎可以在取消令牌方面做些什么,但我弄不清楚如何使用,所以如果那是我的答案,请忽略我的其他胡言乱语。

万一其中一个Polly NuGet开发人员看到这个问题,我希望看到一个重载的WaitAndRetryForever,它以取消令牌作为参数,这样它就可以在被取消时立即返回。 我不确定是否有道理,所以我不敢把它作为正式建议。

这是我目前正在使用的方法:

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;
    }
}
1个回答

9

Execute的重载版中使用了CancellationToken

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

该令牌还将应用于在 WaitAndRetryForever 中处理的延迟。 在线尝试

1
我不知道如何阅读 IntelliSense。我曾尝试将 token 放在正确的位置,但我没有添加本地变量的 ct。现在看起来似乎很明显。谢谢。 - LorneCash

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接