2010-03-08 6 views
5

В моих услугах все открытые методы имеют:Как регистрировать рефакторинг на C#?

try 
{ 
    // the method core is written here 
} 
catch(Exception ex) 
{ 
    Log.Append(ex); 
} 

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

+0

Какие услуги вы имели в виду? WCF, asmx, служба Windows? – empi

+0

@empi self hosting WCF –

ответ

4

Вы можете настроить общий метод обработки ошибок для всех неперехваченных исключений, например, так:

AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledException); 

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

5

Пробег: AOP. Это наиболее широко используемый пункт продажи АОП.

Также см. this discussion здесь, на SO.

+0

wait, пример в указанном вами сообщении в блоге не удаляет 'try-catch'. Он реорганизует только строку 'Log.Append', правильно? –

+0

Аспектно-ориентированное программирование. Вы подходите по-другому. Посмотрите на введение PostSharp для идеи - http://www.sharpcrafters.com/postsharp/documentation/getting-started - таким образом, вы не используете try/catch и т. Д. Для ведения журнала, вы должны использовать атрибут. Очевидно, вам все равно понадобится попробовать/наконец для очистки кода и т. Д. BTW, ссылка postsharp - пример - я не говорю, что это решение, которое вам нужно. –

1

Я как-то использовал что-то вроде шаблона функции шаблона, чтобы решить проблему вроде этого. У меня был базовый класс, который сделал что-то вроде:

public void Execute() 
{ 
    try 
    { 
     ExecuteImplementation(); 
    } 
    catch (Exception ex) 
    { 
     // Log ex 
    } 
} 

public abstract void ExecuteImplementation(); 

Был один производный класс за операцию веб-сервиса. Производные классы каждый реализовал ExecuteImplementation.

Операция веб-служба сделала:

[WebMethod] 
public Result WebOperation(Request request) 
{ 
    WebOperationClass instance = new WebOperationClass(request); 
    instance.Execute(); 
    return instance.Result; 
} 
+0

Ваше решение вдохновило мое собственное, которое я написал здесь как ответ –

4

я придумал полуприцеп решения прямо сейчас. Я могу реорганизовать код:

public TResult ExecuteAndLogOnError(Func<TResult> func) 
{ 
    try 
    { 
     return func(); 
    } 
    catch(Exception ex) 
    { 
     // logging ... 
    } 
} 

И тогда вы можете назвать его по каждому методу:

return ExecuteAndLogOnError(() => 
{ 
    // method core goes here.. 
}); 

Который 4 строки короче оригинального сценария.

+2

Вполне вероятно, что это приведет к ненужным закрытиям. – empi

+0

@empi Что такое закрытие? –

+2

этот вопрос сложнее, чем ваш первоначальный;) http://blogs.msdn.com/ericlippert/archive/2003/09/17/53028.aspx – empi

2

Если все, что вы делаете, регистрируется, то просто зарегистрируйте ошибку на более позднем этапе ... Не нужно регистрировать ошибку раньше. Если вы сделаете больше, чем запишите ошибку, то вам все равно понадобится try..catch. И если вы проглотите исключения (IE просто запишите их, а затем продолжайте, как будто ничего не произошло), возможно, вы делаете это неправильно ...

3

В таких случаях я всегда использую централизованные обработчики ошибок. В WCF это очень просто. Дополнительная информация: http://www.haveyougotwoods.com/archive/2009/06/24/creating-a-global-error-handler-in-wcf.aspx

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

1

Исключительные фильтры были бы хороши для этого. Увы, .NET поддерживает их через MSIL, C++/CLI, VB.NET, но не C#.

+0

ничего себе, никогда не слышал о функции MSIL, отсутствующей на C# –

+0

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

1

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

+0

Я не использую ASP.NET или IIS в этом проекте –

0

Предыдущий плакат поднял АОП (Аспектно-ориентированное программирование).

Я использую PostSharp для основных трасс/исключений ведения журнала.

Очень прост в использовании и настройке.

Ознакомьтесь с этой ссылкой и просмотрите учебное пособие.

http://www.sharpcrafters.com/postsharp

--crap это уже не с открытым исходным кодом ... в любом случае вы не можете захватить Postsharp1.5 и возиться с ним, чтобы увидеть, если это то, что вы заинтересованы в нем.

Я также никоим образом не связан с PostSharp. Я просто пользователь.

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