简体   繁体   中英

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

I'm new to Polly so there may be a completely different approach compared to the one I'm trying to do and that would be perfectly OK.

My goals are this:

  1. token may be canceled due to timeout or request
  2. Retry forever until either success or token is canceled.
  3. When requesting cancellation waits should be exited immediately

Although the method I have worked it seems like I'm missing something and there's probably a better/cleaner way to accomplish what I want. I'm specifically thinking of this line .WaitAndRetryForever(retryAttempt => TimeSpan.Zero, . I feel like I should be able to pass retryDelay in here instead of TimeSpan.Zero but if I do that when cancellation is requested it doesn't return until the retryDelay has completed waiting rather than immediately like I want.

I did see that the .Execute looks like it can do something with a cancellation token but I couldn't figure out how to use that so if that's my answer please ignore my other ramblings.

Just in case one of the Polly NuGet developers sees this what I expected to see was an overload for WaitAndRetryForever that took a cancellation token as a parameter so that it could return immediately if it were canceled. I hesitate to make that an official suggestion because I'm so new to Polly I'm not sure if that makes sense.

This is the method I'm currently using:

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;
    }
}

An overload of Execute takes a CancellationToken :

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

This token will also be applied to the delay handled within WaitAndRetryForever .

Try it online

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM