C# 孪生例外之谜
这里有一个有趣的问题。我有一个系统,试图运行一些初始化代码。如果失败了,我们就叫去初始化器来清理一切 因为我们在异常处理中调用deinitializer,所以我们冒着初始化和deinitialize都将失败的风险,并且假设,现在似乎我们必须抛出两个异常 不过,我们似乎不大可能这样做。那么在这里会发生什么,代码应该做什么呢C# 孪生例外之谜,c#,.net,C#,.net,这里有一个有趣的问题。我有一个系统,试图运行一些初始化代码。如果失败了,我们就叫去初始化器来清理一切 因为我们在异常处理中调用deinitializer,所以我们冒着初始化和deinitialize都将失败的风险,并且假设,现在似乎我们必须抛出两个异常 不过,我们似乎不大可能这样做。那么在这里会发生什么,代码应该做什么呢 try { /* init code here */ } catch (Exception ex) { t
try { /* init code here */ }
catch (Exception ex)
{
try
{
_DeinitializeEngine();
}
catch (Exception ex2)
{
throw new OCRException("Engine failed to initialize; ALSO failed to deinitialize engine!", ex2);
}
finally
{
throw new OCRException("Engine failed to initialize; failed to initialize license!", ex);
}
}
你不应该把最后一块扔进去。相反,使用InnerException在抛出中添加信息 使现代化 您需要做的是捕获异常的历史并重新调用,这是通过InnerException完成的。您可以在构建新异常时对其进行编辑。这是我刚刚编写的代码片段,用于说明我在下面所有注释中解释的想法
static void Main(string[] args)
{
try
{
principalMethod();
}
catch (Exception e)
{
Console.WriteLine("Test : " + e.Message);
}
Console.Read();
}
public static void principalMethod()
{
try
{
throw new Exception("Primary");
}
catch (Exception ex1)
{
try
{
methodThatCanCrash();
}
catch
{
throw new Exception("Cannot deinitialize", ex1);
}
}
}
private static void methodThatCanCrash()
{
throw new NotImplementedException();
}
不需要在finalize中使用双掷。如果你在控制台上放一个断点。WriteLine。。。。您将注意到,您拥有所有异常跟踪。您不应该抛出Finally块。相反,使用InnerException在抛出中添加信息 使现代化 您需要做的是捕获异常的历史并重新调用,这是通过InnerException完成的。您可以在构建新异常时对其进行编辑。这是我刚刚编写的代码片段,用于说明我在下面所有注释中解释的想法
static void Main(string[] args)
{
try
{
principalMethod();
}
catch (Exception e)
{
Console.WriteLine("Test : " + e.Message);
}
Console.Read();
}
public static void principalMethod()
{
try
{
throw new Exception("Primary");
}
catch (Exception ex1)
{
try
{
methodThatCanCrash();
}
catch
{
throw new Exception("Cannot deinitialize", ex1);
}
}
}
private static void methodThatCanCrash()
{
throw new NotImplementedException();
}
不需要在finalize中使用双掷。如果你在控制台上放一个断点。WriteLine。。。。您会注意到,您拥有所有异常跟踪。如果我正确理解您的问题,我会这样做:
try { /* init code here */ }
catch (Exception ex)
{
// Passing original exception as inner exception
Exception ocrex = new OCRException("Engine failed to initialize", ex);
try
{
_DeinitializeEngine();
}
catch (Exception ex2)
{
// Passing initialization failure as inner exception
ocrex = new OCRException("Failed to deinitialize engine!", ocrex);
}
throw ocrex;
}
如果我正确理解了你的问题,我会这样做:
try { /* init code here */ }
catch (Exception ex)
{
// Passing original exception as inner exception
Exception ocrex = new OCRException("Engine failed to initialize", ex);
try
{
_DeinitializeEngine();
}
catch (Exception ex2)
{
// Passing initialization failure as inner exception
ocrex = new OCRException("Failed to deinitialize engine!", ocrex);
}
throw ocrex;
}
如果清理代码失败,并且无法使应用程序保持干净和已知的状态,我会让异常未处理,或者使用未处理的异常事件捕获异常以记录它,然后关闭应用程序
因为如果您不能处理第一个异常,捕获第二个异常有什么意义?如果您的清理代码失败,并且您无法将应用程序保持在干净和已知的状态,我会让该异常未处理,或者使用未处理的异常事件捕获它以记录它,然后关闭应用程序
因为如果您不能处理第一个异常,那么捕获第二个异常又有什么意义呢?您有两种可能的异常情况:一种是第一个方法失败,另一种是两个方法都失败 您已经在定义自己的异常类。因此,使用RelatedException或prioreException属性创建另一个或扩展第一个。在第二种情况下引发异常时,请在此属性中保存对第一个异常的引用
由捕获此异常的异常处理程序决定如何处理第二个异常。您有两种可能的异常情况:一种是第一个方法失败,另一种是两个方法都失败 您已经在定义自己的异常类。因此,使用RelatedException或prioreException属性创建另一个或扩展第一个。在第二种情况下引发异常时,请在此属性中保存对第一个异常的引用
捕获此异常的异常处理程序将决定如何处理第二个异常。@Daok:如果第一个异常未能通过初始化方法,他将抛出一个异常。如果失败了,但是反初始化成功了,那么他仍然希望抛出第一个失败的init异常。不需要在Finally中这样做。如果初始化引擎失败,它将自动启动。另一个catch ex2需要一个InnerException以避免丢失第一个异常…是的,但是如果Init失败,但Deinit成功,那么抛出失败的Init方法的第一个异常的唯一方法是finally.no,因为您需要在DeinitializeEngine成功与否之后进行抛出,因为它已经失败了。。。。我想你不明白我的解释:POK,对不起,我不懂你的英语。我道歉。我明白你在说什么了。您的意思是在调用Denit之后,只在try块本身中抛出第一个异常。是吗?@Daok:如果初始化方法第一件事失败,他就会抛出一个异常。如果失败了,但是反初始化成功了,那么他仍然希望抛出第一个失败的init异常。不需要在Finally中这样做。如果初始化引擎失败,它将自动启动。另一个catch ex2需要一个InnerException以避免丢失第一个异常…是的,但是如果Init失败,但Deinit成功,那么抛出失败的Init方法的第一个异常的唯一方法是finally.no,因为您需要在DeinitializeEngine成功与否之后进行抛出,因为它已经失败了。。。。我想你不明白我的解释:波克,对不起,我不明白
还有你的英语。我道歉。我明白你在说什么了。您的意思是在调用Denit之后,只在try块本身中抛出第一个异常。是吗?你的意思是为第一个catch块编写finally块吗?只有这样,你的解释才是正确的。最后提到的是当初始化代码失败时抛出异常,而不是deinit。我喜欢你的标题,孪生异常之谜。这不是一个哈代男孩的故事,就是某种东方神秘主义一个问题:OCRException是您编写的类吗?您的意思是为第一个catch块编写finally块吗?只有这样,你的解释才是正确的。最后提到的是当初始化代码失败时抛出异常,而不是deinit。我喜欢你的标题,孪生异常之谜。这不是一个哈代男孩的故事,就是某种东方神秘主义一个问题:OCRException是您编写的类吗?我认为该版本可能缺少ex2的某些内容。在这里,我们遇到了一个问题——试图从两个异常中创建一个异常。我认为该版本可能缺少用于ex2的内容。这里我们遇到了一个问题——试图从两个异常中创建一个异常。