Как реализовать логику повтора с помощью параллельной библиотеки задач (TPL)
Возможный дубликат:
Повторить задачу несколько раз на основе пользовательского ввода в случае исключения в задаче
Я ищу способ реализовать логику повтора в 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)
{
}
Ответы
Ответ 1
Любая причина делать что-то особенное с 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)
, чтобы некоторые исключения (например, отмена) прерывались без повторения.
Ответ 2
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);
}