首页 > 解决方案 > 在 Try/Catch 中测试特定的 InnerException

问题描述

我正在客户端处理程序函数中使用 Stream.Read(具有阻塞 I/O)开发 TCP 客户端/服务器应用程序。当我关闭服务器时,我得到一个 IO 异常 {“无法从传输连接读取数据:阻塞操作被 WSACancelBlockingCall 调用中断。”},这是意料之中的。我在 Stream.Read 周围使用 Try/Catch 并想测试此特定异常并忽略它,但仍处理任何其他异常。

我的第一个想法是为 SocketException 中断错误设置一个特定的 Catch,然后为其他任何事情设置一个更通用的 Catch。这未能捕获任何东西,因为抛出的异常不是 SocketException:SocketException 是 IO 异常的 InnerException。

这是我想做的一些伪代码:

Try
    Dim RawDataResp(255) As Byte
    Dim RawRespLen As Integer
    RawRespLen = Stream.Read(RawDataResp, 0, RawDataResp.Length)
    ' do some stuff with my data ...
Catch ex As Exception
    If ex.InnerException IsNot Nothing AndAlso

' The next line gives: 'SocketErrorCode' is not a member of 'Exception'.
        ex.InnerException.SocketErrorCode = SocketError.Interrupted Then

            print("Socket read interrupted; expected on Server shutdown")
    Else
        ' Handle any other exceptions here...
    End If
End Try

似乎我应该能够将 ex 转换为 SocketException(可能使用 GetType ...)以引用 SocketErrorCode,但我似乎找不到正确的语法。谢谢你的帮助

标签: vb.net

解决方案


您可以在语句上使用When子句Catch进行过滤。这就像IfCatch块中使用 an ,只是它允许Catch在条件为 时测试其他语句False。在没有实际测试过的情况下,我认为这应该可行:

Try
    '...
Catch ex As Exception When TryCast(ex.InnerException, SocketException) IsNot Nothing
    'Process any exception where the inner exception is type SocketException.
Catch ex As Exception
    'Process all other exceptions.
End Try

如果需要,您可以使用过滤器获得更具体的信息,例如

Try
    '...
Catch ex As Exception When TryCast(ex.InnerException, SocketException)?.SocketErrorCode = SocketError.Interrupted
    'Process any exception where the inner exception is type SocketException and the error code is Interrupted.
Catch ex As Exception
    'Process all other exceptions.
End Try

注意 null 传播的用户,即?.操作符,NullReferenceException如果没有内部异常或者不是指定的类型,则不会抛出 no。另请注意,第二个Catch块是可选的,您可以简单地允许所有其他异常在此级别未处理。

毫不奇怪, VB中异常处理的文档When包括使用with的解释和示例Catch


推荐阅读