2016-03-11 2 views
1

У меня есть этот метод расширения, который позволяет мне повторить операцию, если есть исключение, типичное использование пытается записать в файл, но по какой-то причине я не могу так немного повторить попытку позже ...Это хорошая практика?

расширение выглядит следующим образом:

public static void WithRetry<T>(this Action action, int timeToWait = 500, int timesToRetry = 3) where T : Exception 
{ 
    int retryCount = 0; 

    bool successful = false; 

    do 
    { 
     try 
     { 
      action(); 
      successful = true; 
     } 
     catch (T) 
     { 
      retryCount++; 
      Thread.Sleep(timeToWait); 
      if (retryCount == timesToRetry) throw; 
     } 
     catch (Exception) 
     { 
      throw; 
     } 
    } while (retryCount < timesToRetry && !successful); 
} 

Visual Studio говорит мне, что я глотание исключения в первом блоке поймать, это плохо?

Спасибо.

+4

Не напрямую связана с вопросом: вы можете опустить последний кетчуп заявление, как вы все это simly вновь бросить исключение. Связано: проглатывание исключений часто плохо, поскольку вы теряете какую-либо информацию об ошибке. – HimBromBeere

+0

Какое точное сообщение вы получаете от Visual Studio? –

+0

Точка выхода '}' проглатывает исключение! Подумайте о том, чтобы исключить исключение. Это предупреждение, а не ошибка. Я делаю исключение, только не первые n раз ... – franklores

ответ

2

Предупреждение - это именно то, чего вы пытаетесь достичь. Вы глотаете исключения (timesToRetry-1) раз. При последней попытке только вы на самом деле бросаете исключение. До тех пор все исключения будут проглочены и потеряны. Поскольку это поведение, которое вы пытаетесь достичь. Нет никакого вреда в подавлении сообщения.

Но, как указано в @HimBromBeere, удалите блок catch(Exception). Также вы можете попробовать зарегистрировать исключение при каждой повторной попытке, потому что вы потеряете эти данные. Что делать, если каждый раз возникает разный вид исключения. Невозможно быть уверенным.

+0

Хороший отзыв о регистрации. Но это метод расширения, как я могу регистрировать исключение? – franklores

+0

Вам необходимо передать объект регистрации в качестве одного из его параметров, чтобы вы могли использовать его для ведения журнала. – CarbineCoder

2

Предупреждение верно, вы проглатываете исключения. Если вы повторите попытку 10 раз, вы никогда не узнаете, что пошло не так в первые 9 раз, вы получите только номер исключения 10.

Возможно, это то, что вы хотите. Лично я бы поместил все возникающие исключения в AggregateException и выбросил , чтобы, когда вы набрали число повторных попыток.

Может быть, как это:

public static void WithRetry<T>(this Action action, int timeToWait = 500, int timesToRetry = 3) where T : Exception 
    { 
     var exceptions = new List<Exception>(); 

     for (int tryIndex = 0; tryIndex < timesToRetry; tryIndex++) 
     { 
      try 
      { 
       action(); 

       return; 
      } 
      catch (T t) 
      { 
       exceptions.Add(t); 
      } 

      Thread.Sleep(timeToWait); 
     } 

     throw new AggregateException(exceptions); 
    } 
+0

Этот ответ мой вопрос о том, как регистрировать промежуточные исключения, при этом это метод расширения. ура – franklores

Смежные вопросы