Попробуйте, поймайте проблему

Я заметил эту проблему, происходящую много в большинстве вещей, которые я делаю, таким образом, я думаю, что должен быть шаблон разработки для этого.

В основном, если исключение выдается, попытка решить проблему и повторную попытку. Если я помещаю его в попытку, все, что это сделает, поймать исключение, но я хочу повторить независимо от того, что это делало и если это перестало работать снова, повторите снова определенное количество раз.

Существует ли общий шаблон для этого вида материала?

12
задан Chris Cudmore 9 February 2010 в 17:56
поделиться

9 ответов

проверьте этот SO-ответ .. надеюсь, что это поможет вам

Самый чистый способ написать логику повтора?

public static class RetryUtility
{
   public static void RetryAction(Action action, int numRetries, int retryTimeout)
   {
       if(action == null)
           throw new ArgumenNullException("action"); 

       do
       {
          try 
          {  
              action(); 
              return;  
          }
          catch
          { 
              if(numRetries <= 0) 
                  throw;  // Avoid silent failure
              else
              {
                  Thread.Sleep(retryTimeout);
                  numRetries--;
              }
          }
       } 
       while(numRetries > 0);
   }
}

Звонок

RetryUtility.RetryAction( () => SomeFunctionThatCanFail(), 3, 1000 );

Благодарность Л.Бушкину

17
ответ дан 2 December 2019 в 04:33
поделиться

Для этого доступна команда Vim : match . Для добавления произвольного количества совпадений можно также использовать функцию matchadd () .

-121--3977955-

Для потока ios:: out является значением по умолчанию, поэтому разницы нет. Я считаю, что единственный раз, указывающий на ios:: out имеет значение, это если вы используете fstream, который можно открыть для чтения или письма, или и то и другое.

-121--4780151-

попробовать/поймать внутри цикла, со счетчиком для повторных попыток?

EDIT: И ваше требование «повторить то, что он делал», вам нужна пользовательская логика для этого, как повторить варьируется дико (то есть, снова открыть поток, воссоздать объект, сделать паузу на X миллисекунд и т.д.), поэтому вам это нужно

Под «атомной операцией» я подразумеваю набор связанных операторов, таких как чтение файла. Например, весь файл, считанный в память, может представлять собой атомарную операцию.

2
ответ дан 2 December 2019 в 04:33
поделиться

В некоторых случаях вы можете захотеть поместить свой try / catch в цикл и принудительно прервать выполнение, если в конечном итоге оно будет успешным. Это может быть для тестирования доступа в Интернет, и вы хотите, чтобы у пользователя была еще одна попытка подключения.

2
ответ дан 2 December 2019 в 04:33
поделиться

Зависит от того, что вы пытаетесь сделать, но обычно вы хотите проверить возможность возникновения исключения ДО выполнения кода, который может вызвать исключение.

Например, проверьте, существует ли файл, прежде чем обращаться к нему, и создайте его (или что-то еще), если это не так.

1
ответ дан 2 December 2019 в 04:33
поделиться

Вы уверены, что здесь правильная методология обработки исключений? Если вы можете «решить проблему», вы, вероятно, сможете обнаружить состояние ошибки до вызова кода, генерирующего исключение.

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

1
ответ дан 2 December 2019 в 04:33
поделиться

Кодирование того, что уже упоминалось другими:

var success = false;
var attempts = 0;
var maxAttempts = 0;

do {
  attempts++;

  try {
    /* your code */
    success = condition;
  } catch(SuperciliousException e) {
    /* recover */
  }
} while(!success && attempts < maxAttempts);
1
ответ дан 2 December 2019 в 04:33
поделиться

Что-то вроде этого, может быть:

int MAX_RETRIES = 5;
for (var attempt=1; attempt <= MAX_RETRIES; attempt++) {
    try {
        DoSomethingThatMightThrow();
    }
    catch (AnExceptionIKnowHowToHandle) {
        if (attempt < MAX_RETRIES)
             continue;

        throw;
    }
}
2
ответ дан 2 December 2019 в 04:33
поделиться

Это выполняется бесконечно, но было бы легко добавить счетчик цикла в предложение while

    var solved = false;
    var tries = 0;

    while (!solved)
    {
         try
         {
            //Do Something
            solved = true;
         }
         catch
         {
             //Fix error
         } 
         finally
         {
              if(solved || IsRediculous(tries))
                 break;

              tries++;
         }
    }
6
ответ дан 2 December 2019 в 04:33
поделиться

Да, довольно часто бывает цикл с несколькими повторными попытками, когда вы выйти из цикла при успехе. Пара вещей:

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

Если вы в конечном итоге потерпите неудачу, вы должны выбросить первое исключение, которое вы поймали, а не последнее. Второе исключение может быть результатом неправильного восстановления после первого сбоя и может не помочь в устранении исходной проблемы.

1
ответ дан 2 December 2019 в 04:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: