【问题标题】:How can I use Polly for retries with a cancellation token?如何通过取消令牌使用 Polly 进行重试?
【发布时间】:2020-01-06 22:25:17
【问题描述】:

我是 Polly 的新手,因此与我尝试做的方法相比,可能有一种完全不同的方法,那完全可以。

我的目标是:

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

虽然我使用的方法似乎缺少一些东西,并且可能有更好/更清洁的方法来完成我想要的。我特别想到这条线.WaitAndRetryForever(retryAttempt => TimeSpan.Zero,。我觉得我应该能够在这里传递 retryDelay 而不是 TimeSpan.Zero 但如果我这样做时请求取消它不会返回直到 retryDelay 完成等待而不是像我想要的那样立即返回。

我确实看到 .Execute 看起来可以使用取消令牌执行某些操作,但我不知道如何使用它,所以如果这是我的答案,请忽略我的其他杂乱无章。

以防万一 Polly NuGet 开发人员看到这一点,我期望看到的是 WaitAndRetryForever 的重载,它将取消令牌作为参数,以便在取消时可以立即返回。我犹豫是否将其作为官方建议,因为我对 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;
    }
}

【问题讨论】:

    标签: c# polly


    【解决方案1】:

    Execute 的重载需要 CancellationToken

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

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

    Try it online

    【讨论】:

    • 我不知道如何阅读 IntelliSense。我曾尝试将token 放在放置它的正确位置,但我没有为局部变量添加ct。现在我看到它似乎很明显。谢谢
    猜你喜欢
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-14
    • 2021-08-21
    • 2014-10-30
    • 1970-01-01
    相关资源
    最近更新 更多