如何防止Debug.Assert(...)显示模态对话框

30

我有一些使用 Debug.Assert(...) 的库。我认为 Debug.Assert(...) 是好的,我仍然希望它们能够执行,但我不希望它们阻止我的应用程序的执行。理想情况下,我只想将它们记录在某个地方。

考虑到我不能更改库的代码(而且我仍然想要在调试中编译并运行断言),如何防止 Debug.Assert(...) 显示模态对话框?

此外,我希望确保当发生 Assert 时,主程序继续运行(与忽略按钮的行为相同)。

谢谢!


1
有趣的是,没人在这里提到,但是Debug.Assert()不会出现在你编译后的应用程序中(当你在发布模式下部署时)。这是严格的调试工具,不会影响最终用户。但是如上所述,如果您不修复断言,您的应用程序可能会发生糟糕的事情。 - NightOwl888
3个回答

31
我不建议这样做。问题在于Debug.Assert只应当在代码中存在缺陷时被触发。如果你忽略或不修复它们,那么你就是在对用户不负责任。另一方面,如果你为并非错误的事情触发Debug.Assert,那么你同样会对用户造成不良影响(减少了Debug.Assert的影响)。
话虽如此,你仍然可以禁用它。首先你需要从 Debug.Listeners 集合中移除默认监听器。
Debug.Listeners.Clear();

然后,添加您自己的内容:
Debug.Listeners.Add(new MyTraceListener());

您需要创建一个从TraceListener继承的类:

class MyTraceListener : TraceListener
{
    // ...

    public override void Fail(string msg, string detailedMsg)
    {
        // log the message (don't display a MessageBox)
    }
}

重要的方法是TraceListener.Fail方法,实现了DefaultTraceListener后会弹出消息框。

这个程序运行得很完美,但是当一个断言失败时,代码就不会继续运行。我希望它能够继续执行。你有什么想法吗? - Martin
5
assertions的目的是在出现错误时触发。如果一个assertion被触发,执行应该停止,因为结果是不可预测的。你试图滥用assertions,应该坚持使用自己的日志记录器。@Martin - Marco de Abreu
2
我们有一个场景,其中存在大量的遗留代码库,散布着正确和不正确使用的断言。当您想要调试特定的代码片段时,您必须穿过数百个断言才能到达您的代码。我们正在逐步清理断言,但在我们的情况下,部分禁用断言是一种有效的临时修复方法,因此这是一个有价值的答案。 - Geordie
也许 OP 想要一个断言,它只在调试时触发,不会打开烦人的 GUI 窗口,而是让应用程序处理异常/日志记录? - CervEd

31

不需要使用Debug.Listeners.Clear()

只需将以下内容添加到你的.config文件中:

<system.diagnostics>
    <assert assertuienabled="false"/>
</system.diagnostics>

这对我很有帮助。我们想要在一些工具中调试插入,而在使用相同共享dll的其他工具中不进行调试插入......完美,只需更改应用程序配置即可。 - Ernst
如何在 .NET Core Web API 中禁用 - Yogesh

5
Codekas的回答是正确的,如果你想用一个非常大的锤子来打东西。你可以在应用程序配置文件中使用<assert>元素将assertuienabled属性设置为false,并可选择给出一个日志文件以写入Asserts。这样你就不必编写自己的监听器了。
你可以在其MSDN页面上阅读有关assert元素的更多信息。

1
这个程序运行得很完美,但是当一个断言失败时,代码就不会继续运行。我希望它能够继续执行。你有什么想法吗? - Martin
@Martin 这个话题有点老了,但是如果你的代码中存在错误,为什么还要继续呢?我的意思是,你对错误结果有什么期望,因为你的任何假设都是错误的? - Christian St.
2
@ChristianSt。你假设第一次正确使用了断言,或者你关心其他人的断言。如果你想要在应用程序中轻松地滑动,直到遇到自己的断点,该怎么办? - Geordie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接