Я никогда не был полностью доволен тем, как работает обработка исключений, есть много исключений и попытка/улов приносит в таблицу (разворачивание стека и т.д.), но, похоже, ломает много модели OO в процесс.
В любом случае, здесь проблема:
Скажем, у вас есть класс, который обертывает или включает операции ввода-вывода в сетевом файле (например, чтение и запись в какой-либо файл по определенному пути UNC). По разным причинам вы не хотите, чтобы эти операции ввода-вывода терпели неудачу, поэтому, если вы обнаружите, что им не удается выполнить повторную попытку, и вы продолжаете повторять их до тех пор, пока они не добьются успеха или не достигнут тайм-аута. У меня уже есть удобный класс RetryTimer, который я могу создать и использовать для спячки текущего потока между повторениями и определить, когда истек период ожидания и т.д.
Проблема заключается в том, что у вас есть несколько операций ввода-вывода в нескольких методах этого класса, и вам нужно обернуть их в логику try-catch/retry.
Вот пример фрагмента кода:
RetryTimer fileIORetryTimer = new RetryTimer(TimeSpan.FromHours(10));
bool success = false;
while (!success)
{
try
{
// do some file IO which may succeed or fail
success = true;
}
catch (IOException e)
{
if (fileIORetryTimer.HasExceededRetryTimeout)
{
throw e;
}
fileIORetryTimer.SleepUntilNextRetry();
}
}
Итак, как вы избегаете дублирования большей части этого кода для каждой операции ввода-вывода файла во всем классе? Моим решением было использовать анонимные блоки делегатов и один метод в классе, который выполнил переданный ему блок делегата. Это позволило мне делать подобные вещи другими способами:
this.RetryFileIO( delegate()
{
// some code block
} );
Мне это нравится, но это оставляет желать лучшего. Я хотел бы услышать, как другие люди решат такую проблему.