【发布时间】:2013-11-23 02:17:18
【问题描述】:
在某些情况下,我只想调用某个方法来完成某些工作,而不关心处理它可能抛出的所有特定异常。相反,我真正关心的是方法是否成功。
我将提供一个 .NET / C# 示例。假设我有一个要复制的文件,我真正关心的是复制操作是否成功。如果复制失败,我不在乎特定异常是 FileNotFoundException 还是 IOException“磁盘空间不足”异常或其他什么...在这种情况下,我的应用程序将正常运行,因为此操作并不重要。
所以实现这个的想法是:
try
{
// try
System.IO.File.Copy(strFile, strFile + ".new");
}
catch (Exception ex)
{
// if critical exception then rethrow
if (IsCritical(ex))
throw;
// else just log and swallow...
Console.WriteLine("Failed to copy the file: " + ex.Message);
}
其中 IsCritical(Exception ex) 是定义为的辅助方法:
public static bool IsCritical(Exception ex)
{
if (ex is OutOfMemoryException) return true;
if (ex is AppDomainUnloadedException) return true;
if (ex is BadImageFormatException) return true;
if (ex is CannotUnloadAppDomainException) return true;
if (ex is ExecutionEngineException) return true;
if (ex is InvalidProgramException) return true;
if (ex is System.Threading.ThreadAbortException)
return true;
return false;
}
此问题基于以下文章:Exception Handling in C# with the "Do Not Catch Exceptions That You Cannot Handle" rule in mind
这个想法是遵循异常处理最佳实践的主要规则: - 不要在不重新抛出的情况下捕获一般异常 - 只捕获你知道如何处理的异常 - (在这种情况下,我想以相同的方式处理它们......通过记录并继续使用应用程序逻辑)。
那么对于给定的场景,这是一个好方法吗?如果不是,为什么以及做什么会更好?
【问题讨论】:
-
就我个人而言,我会通过调用一个体面的日志框架(log4net、NLog、你的名字)来替换
Console.WriteLine("Failed to copy the file: " + ex.Message);,以确保记录更多信息像堆栈跟踪等。 -
问题是,您已经列举了两组异常——您认为很关键的异常和您确定是良性的(当前为 FileNotFoundException 和 IOException)。但肯定有 很多 例外当前不在您的列表中。您确定它们都属于良性类别吗?如果不是,那么他们肯定应该(在没有任何其他知识的情况下)与关键的一样对待吗?
-
不是 .Net 的人,但在 Java 中这样做的方式是它们在异常和错误(都扩展 Throwable )之间有所不同,其中错误是例如 OutOfMemoryError 和异常都是应用程序级别的错误;即IOException。这就是为什么他们说永远不要捕获 Throwable (除非你真的知道你在做什么),这基本上就是参考文章所说的。
标签: c# .net exception exception-handling