安全处理异常时,避免出现第一次机会异常消息


77

以下代码捕获EOS异常

using (var reader = new BinaryReader(httpRequestBodyStream)) {

    try {
        while (true) {
            bodyByteList.Add(reader.ReadByte());
        }
    } catch (EndOfStreamException) { }
}

那么,为什么我的控制台中仍然会出现首次机会异常?

mscorlib.dll中发生类型为'System.IO.EndOfStreamException'的第一次机会异常

有没有办法隐藏这些第一次机会异常消息?

Answers:


79

“优先机会”异常的要点是您看到它们是预先处理的,因此可以在调试时在抛出时停止它们。“第二次机会”异常是没有适当处理程序的异常。有时您想捕获“优先机会”异常,因为重要的是要观察抛出异常时发生的情况,即使有人正在捕获它。

没什么可担心的。这是正常现象。


58
确实,这没什么可担心的,但是它们确实使调试输出日志变得混乱:(
Dimitri C. 2010年

190

为避免看到消息,请右键单击输出窗口,然后取消选中“异常消息”。

但是,如果您想知道何时在不设置断点和重新配置调试器的情况下引发异常,那么看到它们的发生可能会很好。


19

1)在Visual Studio中,您可以更改调试器处理(中断)异常的方式的设置。

转到调试>异常。(请注意,根据您的Visual Studio环境设置,此菜单可能不在菜单中。如果不是,请仅使用“自定义”菜单将其添加到菜单中。)

在那里,您会看到一个对话框,讨论异常以及何时中断它们。

在“公共语言运行时异常”行中,您可以取消选择抛出(如果出现这种情况,则应该停止困扰您),也可以取消选择用户未处理的(我不建议这样做)。

2)您收到的消息不应在控制台中,而应出现在Visual Studio的“输出”窗口中。如果是后者,那么我还没有找到删除它的可能性,但是如果您在没有Visual Studio的情况下运行该应用程序,则不会出现。

希望能有所帮助。


11

与Java不同,.NET异常在处理能力方面非常昂贵,在正常且成功的执行路径中应避免处理异常。

您不仅可以避免在控制台窗口中造成混乱,而且可以提高性能,并使诸如.NET CLR异常之类的性能计数器更有意义。

在此示例中,您将使用

while (reader.PeekChar() != -1)
{
    bodyByteList.Add(reader.ReadByte());
}

1
或者您也可以使用ReadBytes一口气获得所有字节,还可以利用缓冲。但我想这不是问题。
Craig Tyler

9
当然可以。“有没有办法隐藏这些第一次机会异常消息?” -第一次机会异常不会与此循环一起出现。:)
Loudej,2009年

7

我遇到了这个问题,无法弄清楚在哪里引发了异常。因此,我的解决方案是使Visual Studio停止执行此类异常。

  1. 导航到“调试/异常”
  2. 展开“公共语言运行时异常”树。
  3. 展开“系统”分支。
  4. 向下滚动到“ NullReferenceException”所在的位置,然后选中“ throw”复选框,然后取消选中“ user-handled”。
  5. 调试您的项目。

4

如果要进一步控制这些消息,可以添加一个处理程序:

Friend Sub AddTheHandler()
AddHandler AppDomain.CurrentDomain.FirstChanceException, AddressOf FirstChanceExceptionHandler
End Sub

<Conditional("DEBUG")>
Friend Sub FirstChanceExceptionHandler( source As Object,  e As Runtime.ExceptionServices.FirstChanceExceptionEventArgs)
' Process first chance exception

End Sub

如其他注释中所述,这使您可以使它们静音,但仍确保您能够意识到它们。我发现如果将消息和时间戳记记录到文本文件中,可以看到实际抛出了多少个消息。


1
好建议。但是值得注意的是System.Runtime.ExceptionServices仅在.Net 4.0或更高版本中可用。对于那些处理用.Net 3.5(或更旧版本)编写的旧代码的人。
paulsm4 2015年

ASP.NET有效吗?
Kiquenet'3

2

实际上,如果每秒有多个异常,则可以通过检查reader.EndOfStream-value来实现更好的性能。打印出这些异常消息的速度令人难以置信,并且将它们隐藏在Visual Studio中不会加快任何速度。


-1

在VB.NET中:

<DebuggerHidden()> _
Public Function Write(ByVal Text As String) As Boolean
   ...

1
这与问题无关。
约翰·桑德斯

实际上,使用[DebuggerNonUserCode]确实会隐藏“第一次机会异常”消息。我不会感到惊讶,DebuggerHidden也会这样做。
鲁宾

我不确定是否将这些视为例外,但是[DebuggerNonUserCode]不会隐藏任何“托管调试助手”。例如,当我使用XmlSerializer时会收到BindingFailures,但除了从“异常”对话框中取消“抛出异常时不选中BindingFailure”之外,我还没有找到隐藏它的方法。
Anthony Brien

似乎使用DebuggerHiddenAttributejust意味着第一次机会异常将显示在调用方法上,而不是方法本身。
Thorarin

-4

我认为该流将引发此异常,因此您可以尝试缩小范围以捕获它。

在不同的作用域周围再添加一些try catch组合,直到将其实际抛出的地方捕获为止,但是由于您的使用范围内未创建stream对象,因此它似乎发生在您的使用范围之外。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.