C#try {} catch {}

iTE*_*Egg 10 c# exception-handling

嗨,谢谢你的阅读.我是编程和C#和套接字编程的新手.在我的代码中,我尝试捕获问题,以便在我的应用程序中提供故障.下列:

        catch (ArgumentNullException e)
        {
            OnNetworkEvents eventArgs = new OnNetworkEvents("Network Unavailable", e.Message);
            OnUpdateNetworkStatusMessage(this, eventArgs);
        }
        catch (EncoderFallbackException e)
        {
            OnNetworkEvents eventArgs = new OnNetworkEvents("Network Unavailable", e.Message);
            OnUpdateNetworkStatusMessage(this, eventArgs);
        }
        catch (SocketException e)
        {
            OnNetworkEvents eventArgs = new OnNetworkEvents("Network Unavailable", e.Message);
            OnUpdateNetworkStatusMessage(this, eventArgs);
        }
        catch (ArgumentOutOfRangeException e)
        {
            OnNetworkEvents eventArgs = new OnNetworkEvents("Network Unavailable", e.Message);
            OnUpdateNetworkStatusMessage(this, eventArgs);
        }
        catch (ObjectDisposedException e)
        {
            OnNetworkEvents eventArgs = new OnNetworkEvents("Network Unavailable", e.Message);
            OnUpdateNetworkStatusMessage(this, eventArgs);
        }
Run Code Online (Sandbox Code Playgroud)

我只是想知道我是否可以用一个单一替换这个重复的代码:

catch (Exception e) { handle here}
Run Code Online (Sandbox Code Playgroud)

这会有用吗?

再次感谢.

Aar*_*ght 22

不,永远不会捕获System.Exception.我觉得今天的记录很糟糕,但我真的无法强调这一点.你不能处理一个OutOfMemoryException或者AccessViolationException,所以不要抓住它!

至于示例代码,我强烈怀疑一个ArgumentNullExceptionArgumentOutOfRange异常会对应于网络错误.如果是这样,它可能意味着真正应该捕获此异常的组件不是.

"容错"并不意味着"吃掉每个例外,因此应用程序不会崩溃" - 这意味着实际上知道可能出错的事情并正确处理它们.

  • 虽然我在精神上同意,但我不能说"永远不会捕获System.Exception".我有处理大量数据的Windows服务,例如分析超过100k +行,如果某些非结构化数据抛出未处理的异常,这是我无法预料的,​​我抓住这个System.Exception并继续其余的记录和通过我们的日志记录机制发出警报.对不起,但是在无人值守的过程中有一些地方,这些捕获都很有用,尤其是在批量处理时.我的2美分. (13认同)
  • 根据您获得这些错误的原因,您可以执行一些操作.例如,如果你得到一个OutOfMemoryException,因为你试图声明一个4GB大小的byte [].做一揽子陈述是不好的.通常和边缘情况将证明您是例外而不是规则. (4认同)
  • @Aaronaught:"你无法处理OutOfMemoryException".你能解释一下原因吗?我只是尝试执行以下行:"ArrayList array = new ArrayList(500000000);" 并成功捕获了OutOfMemoryException,它只是告诉我我没有足够的内存.程序状态根本没有损坏. (2认同)
  • @Aaronaught:文档还说:"以下Microsoft中间(MSIL)指令抛出OutOfMemoryException:box,newarr,newobj".而这仅仅意味着CLR无法找到给定大小的空闲内存块.它不会扩展或缩小其他对象的内存以支持您的请求.这就是为什么我告诉你,在我的例子中,状态没有被破坏. (2认同)

Gre*_*g D 16

作为一般准则,不要抓住System.Exception. 这是一个坏主意和一个糟糕的代码气味,表明未能掌握异常的目的.我相信这是开发人员认为异常是错误而不是触发异常的代码的结果.

我一直在生产代码中看到这种失败,并且它总是掩盖真正的错误,因为有效和有用的异常被捕获并吞没,使应用程序处于不良状态.这使得追踪失败的根本原因变得更加棘手.

使用您在此处使用的方法捕获异常或多或少是正确的方法.但是,您可能需要考虑改进一些事项:

  1. 通常不会将ArgumentNullExceptionArgumentOutOfRangeException作为运行时网络故障处理(除非确实如此).相反,它应被视为一个逻辑错误,导致程序尽快失败(以便您可以使用调试器尽可能接近故障点进行检查).这通常意味着根本没有捕捉到任何东西ArgumentException.

  2. 考虑检查异常层次结构以查找涵盖您尝试报告的异常的适当基本异常. 例如,(我没有查找过),假设你的三个例外都来自SocketException.您可以通过捕获SocketException而不是三个单独的异常来保存一些输入.但是,只有在报告所有套接字异常时才执行此操作.(这基本上是你原来尝试捕获的更严格的版本Exception)

  3. 因为每个异常处理程序中的两行都是相同的,所以您可以创建一个函数来在处理程序的一行中完成这两行工作.典型的不重复自己的重构.如果要更改报告异常的方式,请考虑更改单个函数比单个处理程序更容易.

  4. 几乎任何重要的I/O(网络和文件都会浮现在脑海中)都会引发一个非常重要的异常处理程序链,因为它可能会出错. 看到很多可能失败的I/O错误报告不是反模式,但它可能是一个很好的代码味道. 像松香新鲜的香味或新鲜出炉的面包.:)