TraceListener,它在失败的断言上抛出异常

时间:2013-02-28 22:31:21

标签: c# .net review design-by-contract trace-listener

DefaultTraceListener(这是唯一的跟踪侦听器,如果没有在app.config中重写)的问题是,如果AssertUiEnabledfalse(即在ASP.NET中)它在失败的断言(调用OutputDebugString),上写一条消息Trace.Assert(false),但继续执行

所以我使用的是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
     }
}

现在我的问题:有没有人看到这种方法有问题?

3 个答案:

答案 0 :(得分:0)

我在Trace.Assert中说异常是个坏主意(不看你的代码)。

Trace.XXXX方法通常用于跟踪内容。对于未来的读者(包括您)来说,了解Trace.Assert实际上会引发异常将是非常令人惊讶的。

看到Trace.Assert(甚至Fail)抛出异常更令人惊讶。 Assert的目的是帮助提前发现问题,而不是杀死应用程序。

我建议您提出自定义方法,清楚地在名称中显示其行为,而不是出现现有方法的意外行为。

答案 1 :(得分:0)

取决于。

我不确定这在ASP.NET场景中是否有用。在调试期间,您希望断言正常运行。抛出异常可能会有点令人困惑。在生产中,您将使用发布版本,因此Trace.Assert语句无论如何都不会执行任何操作。

但是,我们使用类似的技术进行单元测试。您真的不希望您的构建服务器挂起显示“断言失败”消息框。相反,您希望断言导致测试失败。因此,我们使用App.config文件进行单元测试(仅适用于软管!),它会安装与您类似的跟踪侦听器。

答案 2 :(得分:-1)

在Fail()中抛出异常可能导致: 1.调用堆栈会令人困惑,因为在条件失败的地方不会抛出异常。

通常你应该在条件失败的地方附近抛出异常。