Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 孪生例外之谜_C#_.net - Fatal编程技术网

C# 孪生例外之谜

C# 孪生例外之谜,c#,.net,C#,.net,这里有一个有趣的问题。我有一个系统,试图运行一些初始化代码。如果失败了,我们就叫去初始化器来清理一切 因为我们在异常处理中调用deinitializer,所以我们冒着初始化和deinitialize都将失败的风险,并且假设,现在似乎我们必须抛出两个异常 不过,我们似乎不大可能这样做。那么在这里会发生什么,代码应该做什么呢 try { /* init code here */ } catch (Exception ex) { t

这里有一个有趣的问题。我有一个系统,试图运行一些初始化代码。如果失败了,我们就叫去初始化器来清理一切

因为我们在异常处理中调用deinitializer,所以我们冒着初始化和deinitialize都将失败的风险,并且假设,现在似乎我们必须抛出两个异常

不过,我们似乎不大可能这样做。那么在这里会发生什么,代码应该做什么呢

      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的内容。这里我们遇到了一个问题——试图从两个异常中创建一个异常。