Упс, я не заметил, что StartTiming создает новый экземпляр Recorder. Я обновил код, чтобы учесть это. Теперь функция Wrap больше не принимает параметр Recorder, а вместо этого передает созданный рекордер в качестве аргумента делегату действия, переданному вызывающей стороной, чтобы вызывающий мог использовать его при необходимости.
Хммм, мне нужно было сделать что-то очень похожее на этот шаблон, лямбда-выражения, делегат Action и замыкания упрощают задачу:
Сначала определите класс для выполнения упаковки:
public static class RecorderScope
{
public static void Wrap(Action<Recorder> action)
{
Recorder recorder = Recorder.StartTiming();
try
{
action(recorder);
}
catch(Exception exception)
{
recorder.ReportFailure(exception);
}
finally
{
recorder.Stop();
}
}
}
Теперь используйте так:
RecorderScope.Wrap(
(recorder) =>
{
// note, the recorder is passed in here so you can use it if needed -
// if you never need it you can remove it from the Wrap function.
DoSomeWork();
});
Хотя один вопрос - действительно ли желательно, чтобы обработчик перехвата глотал исключение, не перебрасывая его? Обычно это плохая практика.
Кстати, я добавлю к этому шаблону, который может быть полезен. Хотя это не похоже на то, что относится к тому, что вы делаете в этом случае: вы когда-нибудь хотели сделать что-то подобное выше, где вы хотите обернуть некоторый код набором действий при запуске и действиями по завершению, но вы также должны быть возможность кодировать какой-то конкретный код обработки исключений. Что ж, если вы измените функцию Wrap, чтобы она также принимала делегат Action и ограничивало T до Exception, тогда у вас есть оболочка, которая позволяет пользователю указать тип исключения, который нужно перехватить, и код, который нужно выполнить для его обработки, например: 1015 *
public static class RecorderScope
{
public static void Wrap(Action<Recorder> action,
Action<Recorder, T1> exHandler1)
where T1: Exception
{
Recorder recorder = Recorder.StartTiming();
try
{
action(recorder);
}
catch(T1 ex1)
{
exHandler1(recorder, ex1);
}
finally
{
recorder.Stop();
}
}
}
Для использования .. (Обратите внимание, вы должны указать тип исключения, так как оно, очевидно, не может быть выведено. Что вам нужно):
RecorderScope.Wrap(
(recorder) =>
{
DoSomeWork();
},
(recorder, MyException ex) =>
{
recorder.ReportFailure(exception);
});
Затем вы можете расширить этот шаблон, предоставив несколько перегрузок функции Wrap, которые принимают более одного делегата обработчика исключений. Обычно достаточно пяти перегрузок - довольно необычно для вас перехватывать более пяти различных типов исключений одновременно.