在维护我同事的代码时,即使是自称是高级开发人员的人,我也经常看到以下代码:
try { //do something } catch { //Do nothing }
或者有时他们将日志信息写入日志文件,如以下try catch块
try catch
try { //do some work } catch(Exception exception) { WriteException2LogFile(exception); }
我只是想知道他们所做的是否是最佳做法?这让我感到困惑,因为在我看来,用户应该知道系统会发生什么。
我的异常处理策略是:
要通过挂钩来捕获 所有未处理的异常Application.ThreadException event,然后决定:
Application.ThreadException event
然后我总是将 在外部运行的每一段代码 都包含在try/catch:
try/catch
然后我附在“尝试/捕获”中
ApplicationException("custom message", innerException)
此外,我尽我所能 正确地对异常进行排序 。有以下例外情况:
需要立即显示给用户
当它们发生时需要一些额外的处理来将它们放在一起以避免级联问题(即:在填充期间将 .EndUpdate 放在finally部分中TreeView)
finally
TreeView
用户不在乎,但重要的是要知道发生了什么。所以我总是记录它们:
在事件日志中
或在磁盘上的 .log 文件中
设计一些静态方法来处理 应用程序顶级错误处理程序中的异常是一种很好的做法。
我也强迫自己尝试:
所以最后:
坏的:
// DON'T DO THIS; ITS BAD try { ... } catch { // only air... }
无用:
// DON'T DO THIS; IT'S USELESS try { ... } catch(Exception ex) { throw ex; }
最后尝试没有捕获是完全有效的:
try { listView1.BeginUpdate(); // If an exception occurs in the following code, then the finally will be executed // and the exception will be thrown ... } finally { // I WANT THIS CODE TO RUN EVENTUALLY REGARDLESS AN EXCEPTION OCCURRED OR NOT listView1.EndUpdate(); }
我在顶层做什么:
// i.e When the user clicks on a button try { ... } catch(Exception ex) { ex.Log(); // Log exception -- OR -- ex.Log().Display(); // Log exception, then show it to the user with apologies... }
我在一些被调用的函数中做了什么:
// Calculation module try { ... } catch(Exception ex) { // Add useful information to the exception throw new ApplicationException("Something wrong happened in the calculation module:", ex); } // IO module try { ... } catch(Exception ex) { throw new ApplicationException(string.Format("I cannot write the file {0} to {1}", fileName, directoryName), ex); }
异常处理(自定义异常)有很多关系,但我尝试记住的那些规则对于我所做的简单应用程序来说已经足够了。
这是一个扩展方法的示例,可以以一种舒适的方式处理捕获的异常。它们以可以链接在一起的方式实现,并且很容易添加自己的捕获异常处理。
// Usage: try { // boom } catch(Exception ex) { // Only log exception ex.Log(); -- OR -- // Only display exception ex.Display(); -- OR -- // Log, then display exception ex.Log().Display(); -- OR -- // Add some user-friendly message to an exception new ApplicationException("Unable to calculate !", ex).Log().Display(); } // Extension methods internal static Exception Log(this Exception ex) { File.AppendAllText("CaughtExceptions" + DateTime.Now.ToString("yyyy-MM-dd") + ".log", DateTime.Now.ToString("HH:mm:ss") + ": " + ex.Message + "\n" + ex.ToString() + "\n"); return ex; } internal static Exception Display(this Exception ex, string msg = null, MessageBoxImage img = MessageBoxImage.Error) { MessageBox.Show(msg ?? ex.Message, "", MessageBoxButton.OK, img); return ex; }