C# 如何使用任务并行库(TPL)实现重试逻辑

C# 如何使用任务并行库(TPL)实现重试逻辑,c#,.net,task-parallel-library,C#,.net,Task Parallel Library,可能重复: 我正在寻找一种在TPL中实现重试逻辑的方法。我希望有一个通用函数/类,它能够返回一个任务,该任务将执行给定的操作,如果出现异常,将重试该任务,直到给定的重试次数。我尝试使用ContinueWith并让回调函数在出现异常时创建一个新任务,但它似乎只适用于固定的重试次数。有什么建议吗 private static void Main() { Task<int> taskWithRetry = CreateTaskWithRetry(DoSom

可能重复:

我正在寻找一种在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)
    {

    }
private static void Main()
{
Task taskWithRetry=CreateTaskWithRetry(剂量测量,10);
taskWithRetry.Start();
// ...
}
专用静态整数剂量测量()
{
抛出新的NotImplementedException();
}
私有静态任务CreateTaskWithRetry(Func操作,int retryCount)
{
}

有什么理由对第三方物流做一些特别的事情吗?为什么不为
Func
本身做一个包装器呢

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--;
            }
        }
    };
}
public static Func Retry(Func original,int retryCount)
{
return()=>
{
while(true)
{
尝试
{
返回原件();
}
捕获(例外e)
{
如果(retryCount==0)
{
投掷;
}
//TODO:日志记录
重新计数--;
}
}
};
}
请注意,您可能需要添加一个
ShouldRetry(Exception)
方法,以允许某些异常(例如取消)在不重试的情况下中止。

私有静态任务CreateTaskWithRetry(Func action,int-retryCount)
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);
}
{ Func retryAction=()=> { int attemptNumber=0; 做 { 尝试 { attemptNumber++; 返回动作(); } catch(Exception异常)//使用您的 { //如果需要,记录错误 if(attemptNumber==retryCount) 投掷; } } while(attemptNumber
将每个操作(重试后)作为单独的任务运行不是更好吗?@Amos:为什么?这样做的好处是什么?这类似于在任务A完成后使用ContinueWith来执行任务B,而不是让单个任务先执行任务A,然后执行任务B。这样,其他线程可以在多次重试后继续执行任务B,而不是在所有重试都完成之后。您可以发布一个使用异步方法的重试包装器的示例吗?@SuperJMN:它不是为异步操作设计的;我会换一种方式。我希望每次重试都能在一个单独的任务上完成。这类似于在任务A完成后使用ContinueWith来执行任务B,而不是一个任务先执行A,然后执行B。这样,其他线程可以在多次重试后继续执行,而不是在所有重试完成后继续执行。