C#try {} catch {}

嗨,谢谢你的阅读。 我是编程和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); } 

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

 catch (Exception e) { handle here} 

这会有用吗?

再次感谢。

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

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

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

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

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

使用您在此处使用的方法捕获exception或多或少是正确的方法。 不过,您可能需要考虑改进一些事项:

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

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

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

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

这肯定会抓住所有例外,但这可能是不好的做法。 有些例外情况会被隐藏或误传,这会使测试和调试应用程序变得更加困难。

正如之前的所有评论所暗示的那样,你应该捕获所有“已知”exception,包括exception特定的catch块和其他未知的,或者更恰当的,所有“无法匹配”的exception与catch (Exception ex) { ... }或者只是catch { ... }

但是,正如您的代码中所指定的那样,您以相同的方式处理所有类型的exception。 所以在这种特殊情况下,输出(你称之为Fault Tolerance )将是相同的,但性能会提高(因为运行时不需要将exception类型与给定的类型列表进行比较)。

故事的道德:在这种特殊情况下使用单一的常见尝试。 但总的来说,避免这种习惯。

你可以,但你会失去粒度和单独处理每个问题的能力,这不是最好的做法。 通常,您将首先处理不同类型的exception,就像您拥有的那样,如果您需要对任何未处理的exception执行某些操作,则可以在末尾添加Exception 。 完成后重新抛出它以保留堆栈跟踪并让它冒泡。

保留你最后添加基础案例的内容:

 catch (ArgumentNullException e) { ... } catch (EncoderFallbackException e) { ... } catch (SocketException e) { ... } catch (ArgumentOutOfRangeException e) { ... } catch (ObjectDisposedException e) { ... } catch (Exception e) { // not handled by above exceptions, do something if needed throw; // after doing what you need, re-throw it } 

它会工作,但它也会捕获“空引用”exception和抛出的任何其他随机exception。

是的它会起作用 ,但它不会这样做,因为所有的例外而不仅仅是特定的例外。

这通常不是您想要的,因为一般规则是只捕获您知道如何处理的exception。 在某些情况下,你需要这样一个catch-all来重定向exception(比如跨线程边界或异步调用)或者做一些清理工作,如果有什么东西 – 什么 – 出错了(但是你经常在做完之后重新抛出exception)你的工作)。

它将捕获从Exception类inheritance的所有exception。 如果它们都以相同的方式处理,那么你就不应该这样做,因为你不能以同样的方式处理从Exceptioninheritance的所有exception。

我今天早上刚刚在这个主题上阅读了一篇博文 。

你可以做一些像post评论中提到的事情:

 catch(Exception e){ if( e is ArgumentNullException || e is EncoderFallbackException || e is ...whatever ){ OnNetworkEvents eventArgs = new OnNetworkEvents("Network Unavailable", e.Message); OnUpdateNetworkStatusMessage(this, eventArgs); } else { throw; } } 

虽然你可以做到这一点,但我认为这是一种糟糕的做法,而不是你想要如何构建你的代码。

根据例外情况,您可能希望做一些不同的事情。 无效IP是与硬件错误等不同的问题。 此外,您可能希望通过委托或使用log4net在某处通知某些内容来返回UI。

但这只是我而且我远非专家 – 所以把它当作它的价值

IMO:

捕获Exception非常类似于具有参数的方法,这些参数从不比Object更具体。 当然你可以做到,但它真的是10次中最好的决定吗?

您应该考虑采取哪些措施来简化代码,这是在相关的最高定义下捕获exception。

例如,在java中我会

 try{...} catch( IOException e ) {...} 

捕获所有与IO相关的exception。

有太多东西可以抛出太多不同类型的exception,你通常应该避免使用Exception的catch-all。