好的,据我所知,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 块执行。我看到它确实如此。
答案 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()) };
}
}