如何用任务并行库实现重试逻辑

本文关键字:重试 实现 何用 任务 并行 | 更新日期: 2023-09-27 17:57:26

可能重复:
在任务中出现异常的情况下,根据用户输入多次重试任务

我正在寻找一种在TPL中实现重试逻辑的方法。我想要一个通用函数/类,它将能够返回一个任务,该任务将执行给定的操作,并且在出现异常的情况下,将重试该任务,直到给定的重试次数。我试着玩ContinueWith,并让回调在出现异常时创建一个新任务,但它似乎只适用于固定次数的重试。有什么建议吗?

    private static void Main()
    {
        Task<int> taskWithRetry = CreateTaskWithRetry(DoSometing, 10);
        taskWithRetry.Start();
        // ...
    }
    private static int DoSometing()
    {
        throw new NotImplementedException();
    }
    private static Task<T> CreateTaskWithRetry<T>(Func<T> action, int retryCount)
    {
    }

如何用任务并行库实现重试逻辑

有什么理由对TPL做一些特别的事情吗?为什么不为Func<T>本身制作一个包装呢?

public static Func<T> Retry(Func<T> original, int retryCount)
{
    return () =>
    {
        while (true)
        {
            try
            {
                return original();
            }
            catch (Exception e)
            {
                if (retryCount == 0)
                {
                    throw;
                }
                // TODO: Logging
                retryCount--;
            }
        }
    };
}

请注意,您可能希望添加一个ShouldRetry(Exception)方法,以允许某些异常(例如取消)在不重试的情况下中止。

private static Task<T> CreateTaskWithRetry<T>(Func<T> action, int retryCount)
{
    Func<T> retryAction = () =>
    {
        int attemptNumber = 0;
        do
        {
            try
            {
                attemptNumber++;
                return action();
            }
            catch (Exception exception) // use your the exception that you need
            {
                // log error if needed
                if (attemptNumber == retryCount)
                    throw;
            }
        }
        while (attemptNumber < retryCount);
        return default(T);
    };
    return new Task<T>(retryAction);
}