简体   繁体   中英

Async generic retry

I have this

public static async Task Retry<T>(Func<T> action, TimeSpan retryInterval, int maxAttemptCount = 3)
{
    var exceptions = new List<Exception>();

    for (int attempted = 0; attempted < maxAttemptCount; attempted++)
    {
        try
        {
            if (attempted > 0)
            {
                Thread.Sleep(retryInterval);
            }
            return await action();
        }
        catch (Exception ex)
        {
            exceptions.Add(ex);
        }
    }
    throw new AggregateException(exceptions);
}

and try to run this by

await Retry(() => SaveFile(command, tracker.ActivityId, blobService), TimeSpan.FromSeconds(5), retryCount);

but i got error in Retry in return await action() (T does not contain definition for getAwaiter)

i need to return from the loop when action is done

and my action

Task SaveFile<TCommand>(TCommand command, string activityId, IBlobService blobService) where TCommand : DomainComman

There are a few issues here.

  1. action returns T , you cannot await this, you can only await Task or Task<T> . So if you want to await action it should have the signature Func<Task<T>>
  2. Your return type is wrong. It looks like you want to return a T , then the return type should be Task<T>
  3. If you are using asynchronous code you should not be using Thread.Sleep , use Task.Delay instead, and await this.

You might also want to add some logging, or a custom exception to make it clearer that this was a repeated failure. Someone looking at a aggregate exception with three duplicates might not immediately figure out what is going on.

Async functions returns Task for beeing awaitable. So in your code you TResult is T and you need to redifine the Func<T> to Func<Task<T>> .

As you return the result of action you need also to change the return type of your function to Task<T>

So you end up with:

public static async Task Retry<T>(Func<T> action, TimeSpan retryInterval, int maxAttemptCount = 3)

as SaveFile seams also to be async so you should change the call to:

await Retry(async () => await SaveFile(command, tracker.ActivityId, blobService), TimeSpan.FromSeconds(5), retryCount);

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