繁体   English   中英

异步通用重试

[英]Async generic retry

我有这个

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

并尝试运行它

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

但我在返回等待操作()时重试时出错(T 不包含 getAwaiter 的定义)

动作完成后我需要从循环中返回

和我的行动

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

这里有几个问题。

  1. action返回T ,你不能等待这个,你只能等待TaskTask<T> 所以如果你想等待action ,它应该有签名Func<Task<T>>
  2. 你的返回类型是错误的。 看起来你想返回一个T ,那么返回类型应该是Task<T>
  3. 如果您使用的是异步代码,则不应使用Thread.Sleep ,而应使用Task.Delay并等待它。

您可能还想添加一些日志记录或自定义异常,以更清楚地表明这是一次重复的失败。 查看包含三个重复项的聚合异常的人可能不会立即弄清楚发生了什么。

异步函数返回可等待的任务。 因此,在您的代码中,您 TResult 是 T 并且您需要将Func<T>重新定义为Func<Task<T>>

当您返回操作结果时,您还需要将函数的返回类型更改为Task<T>

所以你最终得到:

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

因为 SaveFile 接缝也是异步的,所以您应该将调用更改为:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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