2013-02-28 7 views
2

Моей проблемы с DefaultTraceListener (это единственным следом слушатель, если не переопределена в app.config) является то, что, если AssertUiEnabled является false (т.е. в ASP.NET) он пишет сообщение OutputDebugString о неудачных утверждениях (вызовы Trace.Assert(false)), , но продолжает выполнение.TraceListener, который бросает исключение на неудавшееся утверждении

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

TraceListenerWhichThrowsExceptionOnFail.InsertAsFirstTraceListener(Trace.Listeners); 

в Application_Init.

Теперь, в событии Application_Error, я могу регистрировать исключение (как любое исключение) с полной трассировкой стека, включая вызов Trace.Assert(false).

public class TraceListenerWhichThrowsExceptionOnFail : TraceListener 
{ 
    public static void InsertAsFirstTraceListener(TraceListenerCollection traceListeners) 
    { 
     traceListeners.Insert(0, new TraceListenerWhichThrowsExceptionOnFail()); 
    } 

    public override void Fail(string message, string detailMessage) 
    { 
     message = string.IsNullOrEmpty(detailMessage) ? message : message + ", Detail message: " + detailMessage; 

     throw new ApplicationException("Trace assertion failed" + 
      (string.IsNullOrEmpty(message) ? "" : ": " + message) + "."); 
    } 

    public override void Write(string message) 
    { 
     // NOP 
    } 

    public override void WriteLine(string message) 
    { 
     // NOP 
    } 
} 

Теперь мой вопрос: Кто-нибудь видит проблему с этим подходом?

+1

Похоже, что вопрос более подходит для обзора кода сайта –

ответ

0

Я бы сказал, что исключение в Trace.Assert - плохая идея (не глядя на ваш код).

Методы Trace.XXXX обычно используются для отслеживания материала. Для будущих читателей (включая вас) было бы очень удивительно узнать, что Trace.Assert действительно выдает исключение.

Еще более удивительно видеть исключение Trace.Assert (или даже Fail). Цель Assert - помочь выявить проблемы заранее, а не убивать приложение.

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

+0

'Trace.Assert' не генерирует исключения. 'Trace.Assert (false)' (который выражает, что что-то пошло не так). – moop

+0

@meepgoose, не уверен, что вы комментируете. Я прочитал ваш вопрос как «нормально ли делать особый метод, чтобы вести себя так, как многие люди не ожидают (например, исключение броска, когда нормальное поведение никогда не бросается независимо от аргументов)» и ответил так. Мое понимание ожидаемого поведения очень хорошо может быть неправильным, поэтому проверяйте людей, с которыми вы знаете/работаете, если кто-то ожидает поведения, которое вы внедрили. –

+0

Я нахожусь с этим. В то время как Trace.Методы XXX', как правило, предназначены для отслеживания материала, я мог бы также легко аргументировать, что методы 'XXX.Assert', как правило, предназначены для остановки выполнения вашей программы из-за некоторого инвариантного нарушения в вашей логике. Более того, я также хотел бы заявить, что «Trace.Assert» является эквивалентом режима выпуска Debug.Assert. Сам MSDN говорит: * Используйте метод Trace.Assert, если вы хотите делать утверждения в сборках релизов. Метод Debug.Assert работает только в отладочных сборках *. Под этой предпосылкой смысл «Trace.Assert» бросать, чем журнал. –

0

Это зависит.

Я не уверен, что это было бы полезно в сценарии ASP.NET. Во время отладки вы хотите, чтобы утверждения велись нормально. Выбросы исключений, вероятно, были бы немного запутанными. И в производстве вы будете использовать выпуски, так что операторы Trace.Assert ничего не сделают.

Однако мы используем аналогичную технику для модульных испытаний. Вы действительно не хотите, чтобы ваш сервер сборки висел, отображая сообщение «Assertion Failed». Вместо этого вы хотите, чтобы ваши утверждения приводили к сбою тестов. Поэтому мы используем файл App.config для наших модульных тестов (и только для шлангов!), Который устанавливает прослушиватель трассировки, который похож на ваш.

+0

Конфигурация «Release» по умолчанию (которую я не изменил) позволяет использовать условие «TRACE». Вы имеете в виду условие «DEBUG» (разрешено только в конфигурации «Отладка»). – moop

-1

Выброс исключения в Fail() может привести к: 1. стек вызовов будет путать, поскольку исключение не выбрасывается рядом с условием отказа.

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