VB.NET尝试使用多个Catch块捕获

Dan*_*Dan 25 .net vb.net exception-handling exception .net-4.0

这是一个非常奇怪的问题.我们有一个包含多个Catch块的Try Catch.第一个Catch块没有代码,只有注释.

Try
  'Some Code
Catch ex As ThreadAbortException
  'Do Nothing
Catch ex As Exception
  HandleException(ex)
End Try
Run Code Online (Sandbox Code Playgroud)

如果抛出ThreadAbortException以外的异常,则会被第二个Catch捕获,如预期的那样.但是,当在VS2010中单步执行代码时,ex对象在这种情况下是Nothing.到目前为止,我们已经找到了两种"修复"此问题的方法.

修复1:重命名第一个异常变量.

Try
  'Some Code
Catch tex As ThreadAbortException
  'Do Nothing
Catch ex As Exception
  HandleException(ex)
End Try
Run Code Online (Sandbox Code Playgroud)

修复2:将任何代码行添加到第一个Catch块.

Try
  'Some Code
Catch ex As ThreadAbortException
  Dim i As Integer = 1
Catch ex As Exception
  HandleException(ex)
End Try
Run Code Online (Sandbox Code Playgroud)

在任何上述情况下,HandleException中的代码在运行时似乎仍能正常运行.这是Visual Studio或调试器中的错误吗?或者我们在这里遗漏了什么,上面第一段代码无效?

这一切都在.NET 4.0中完成.

Kon*_*lph 15

Teejay有正确的答案.

但是,如果您的Catch块为空,则完全没有理由处理此异常.你只是想阻止最后一个块捕获它.你可以使用你的方法 - 但是考虑到一个空Catch块通常是不可接受的:异常应该被捕获,或者应该被正确处理; 静静地吞咽它们必须被视为一种虫子.您的情况是此规则的一个例外,但因此需要在代码中记录,因为否则会使精心维护者感到困惑.

那么,VB对于这种情况有一个特殊的习惯用语:

Try
    ' …
Catch ex As Exception When Not TypeOf ex Is ThreadAbortException
    ' Only executed if `ex` isn’t a ThreadAbortException
End Try
Run Code Online (Sandbox Code Playgroud)

这段代码根本没有捕获ThreadAbortException,如果你不想处理它,这是正确的事情:ThreadAbortException 不能吞下它,所以即使你抓住它,它也会在Catch块的末尾重新抛出.

请注意,这与SysDragon使用常规If语句的答案根本不同,而此处的代码在语句中使用特殊子句Catch作为过滤器.


Tee*_*jay 5

它似乎是一个VS'调试器错误.

证明

如果你写:

Try
    Throw New InvalidOperationException("MESSAGE")
Catch ex As ArgumentException
    'Do Nothing
Catch ex As Exception
    Debug.WriteLine(ex)
End Try
Run Code Online (Sandbox Code Playgroud)

并且你看exNothingQuickwatch模式下评估

在控制台中程序正确打印 System.InvalidOperationException: MESSAGE