最后在try / catch中阻塞不起作用?

时间:2014-03-13 07:52:12

标签: c# oop exception exception-handling

好的,据我所知,try / catch块尝试操作并捕获块捕获异常。更具体的异常排在最前面,对于一系列catch块的底部越通用。在下面的代码中,我实现了try / catch,一切正常。

据我所知,finally块始终执行。有些人认为没有目的最终阻止,因为如果有异常或者没有,那么最后一个catch块之后的代码无论如何都会被执行。

但是,反对这一点的论点是,如果在catch块中抛出了异常,则没有后续的catch块来捕获该异常。因此,通过将资源清理代码放在finally块中,可以确保在catch块中抛出异常时释放资源。

这就是为什么以下代码让我困惑的原因。我在第一个catch块中抛出异常,finally块永远不会执行。为什么呢?

*请注意,创建myStreamReader时确实会抛出异常,因为该文件实际上被称为generic.txt,并且有目的拼写错误,以便抛出初始异常。

StreamReader myStreamReader = null;

try
{
   myStreamReader = new StreamReader("c:\\genneric.txt");   
   Console.WriteLine(myStreadReader.ReadToEnd());       
}

catch(FileNotFoundException Error)
{
   Console.WriteLine(Error.Message);
   Console.WriteLine(); 
   throw new Exception();
}

catch(Exception Error)
{
   Console.WriteLine(Error.Message);
   Console.WriteLine();
}

finally
{

  if(myStreamReader != null)
  {
    myStreamReader.Close();
  }

  Console.WriteLine("Closed the StreamReader.");
}

VIDEO:

此代码块的问题源于此视频,时间为27:20:

https://www.youtube.com/watch?v=WxdSb3ZCWYc&list=PLAC325451207E3105&index=41

该人直接声明 catch 块中发生的异常不会阻止 finally 块执行。我看到它确实如此。

4 个答案:

答案 0 :(得分:7)

如果新的异常完全未处理,整个过程将被拆除,finally块永远不会运行。

如果在更高级别有其他异常处理程序,或者安装了未处理的异常处理程序,finally运行。


此示例确实显示"关闭StreamReader":

    static void Main()
    {
        try
        {
            StreamReader myStreamReader = null;

            try
            {
                myStreamReader = new StreamReader("c:\\genneric.txt");
                Console.WriteLine(myStreamReader.ReadToEnd());
            }

            catch (FileNotFoundException Error)
            {
                Console.WriteLine(Error.Message);
                Console.WriteLine();
                throw new Exception();
            }

            catch (Exception Error)
            {
                Console.WriteLine(Error.Message);
                Console.WriteLine();
            }

            finally
            {

                if (myStreamReader != null)
                {
                    myStreamReader.Close();
                }

                Console.WriteLine("Closed the StreamReader.");
            }
        }
        catch
        {

        }
        Console.WriteLine("Done");
        Console.ReadLine();
    }

未处理的异常处理程序可以在AppDomain.UnhandledException事件中注册。

答案 1 :(得分:3)

您的理解不正确。请参阅try-finally

  

通过使用finally块,您可以清理所有资源   在try块中分配,即使异常也可以运行代码   发生在try块中。通常,finally块的语句   当控件离开try语句时运行。控制权的转移可以   由于正常执行,执行休息,   继续,转到或返回语句,或传播异常   在try语句之外。

所以如果你从try块中返回,最后会执行,但是如果从catch块中抛出则不会执行。

  

但是,如果异常未处理,则执行finally块   取决于如何触发异常展开操作。那,   反过来,取决于您的计算机的设置方式。

答案 2 :(得分:1)

假设找不到该文件,它将首先捕获FileNotFoundException

catch(FileNotFoundException error)
{
    Console.WriteLine(error.Message);
    Console.WriteLine(); 
    throw new Exception();
}

这会将消息写入控制台,然后抛出新的Exception。但是,此异常未处理,将停止执行。如果从Catch块中抛出异常,则不会被任何后续块捕获。

解决方案是适当地处理异常,而不是抛出新的异常。如果找不到该文件,则对其进行操作,例如让用户选择另一个文件,创建文件等。

答案 3 :(得分:0)

使用throw代替尝试此操作。抛出新异常时,实际异常将丢失。但是当你只使用throw时,它会抛出FileNotFoundException的实际异常。

StreamReader myStreamReader = null;

try
{
   myStreamReader = new StreamReader("c:\\genneric.txt");   
   Console.WriteLine(myStreadReader.ReadToEnd());       
}

catch(FileNotFoundException Error)
{
   Console.WriteLine(Error.Message);
   Console.WriteLine(); 
   throw;
}

catch(Exception Error)
{
   Console.WriteLine(Error.Message);
   Console.WriteLine();
}

finally
{
  Console.WriteLine("Closing the StreamReader.");
  try{
    if(myStreamReader != null)
   {
      myStreamReader.Close();
   }
  } catch(Exception e) {  Console.WriteLine(e.ToString())  };
}


}