try catch finally简单的三个关键字,其处理流程却较为复杂,下面先分各种情况讨论,最后得出结论,并提出使用建议。
1 没有发生异常的情况
class Program
{
static void Main(string[] args)
{
try
{
//throw new Exception("my exception");
Console.WriteLine("in try");
}
catch (Exception ex)
{
Console.WriteLine("in catch: " + ex.Message);
}
finally
{
Console.WriteLine("in finally");
}
Console.WriteLine("after finally");
}
输出为:
in try
in finally
after finally
分析:
由于没有发生异常,catch也就捕获不到,所以不执行catch里的代码,执行finally的代码,然后执行后续代码。
2.发生异常,并且被本级catch捕获
class Program
{
static void Main(string[] args)
{
try
{
throw new Exception("my exception");
Console.WriteLine("in try");
}
catch (Exception ex)
{
Console.WriteLine("in catch: " + ex.Message);
}
finally
{
Console.WriteLine("in finally");
}
Console.WriteLine("after finally");
}
}
执行结果:
in catch: my exception
in finally
after finally
分析:
try块发生异常的语句以后的代码不再执行,而是马上被catch捕获,并执行catch块里的代码,然后执行finally块的代码,然后执行后续代码。
3 发生异常,被上级catch捕获
代码:
class Program
{
static void Main(string[] args)
{
try
{
test();
Console.WriteLine("in 上一级try");
}
catch (Exception ex)
{
Console.WriteLine("in 上一级catch: " + ex.Message);
}
finally
{
Console.WriteLine("in 上一级finally");
}
Console.WriteLine("after 上一级的finally");
}
static void test()
{
try
{
throw new Exception("my exception");
Console.WriteLine("in try");
}
catch (IOException ex)
{
Console.WriteLine("in catch: " + ex.Message);
}
finally
{
Console.WriteLine("in finally");
}
Console.WriteLine("after finally");
}
}
class Program
{
static void Main(string[] args)
{
try
{
test();
Console.WriteLine("in 上一级try");
}
catch (Exception ex)
{
Console.WriteLine("in 上一级catch: " + ex.Message);
}
finally
{
Console.WriteLine("in 上一级finally");
}
Console.WriteLine("after 上一级的finally");
}
static void test()
{
try
{
throw new Exception("my exception");
Console.WriteLine("in try");
}
catch (IOException ex)
{
Console.WriteLine("in catch: " + ex.Message);
}
finally
{
Console.WriteLine("in finally");
}
Console.WriteLine("after finally");
}
}
class Program
{
static void Main(string[] args)
{
try
{
test();
Console.WriteLine("in 上一级try");
}
catch (IOException ex)
{
Console.WriteLine("in 上一级catch: " + ex.Message);
}
finally
{
Console.WriteLine("in 上一级finally");
}
Console.WriteLine("after 上一级的finally");
}
static void test()
{
try
{
throw new Exception("my exception");
Console.WriteLine("in try");
}
catch (IOException ex)
{
Console.WriteLine("in catch: " + ex.Message);
}
finally
{
Console.WriteLine("in finally");
}
Console.WriteLine("after finally");
}
}
执行结果:
未经处理的异常: System.Exception: my exception
在 ConsoleApplication4.Program.test() 位置 D:\MyProjects\VS2010 Projects\Cons
oleApplication4\ConsoleApplication4\Program.cs:行号 33
在 ConsoleApplication4.Program.Main(String[] args) 位置 D:\MyProjects\VS2010
Projects\ConsoleApplication4\ConsoleApplication4\Program.cs:行号 15
in finally
in 上一级finally
分析:
异常发生后,本级catch没有捕获到,流转到上一级catch,上一级catch也没有捕获到,继续流转直到CLR,CLR会打印“未处理...",并在用户按下取消按钮后,执行本级的finally块,然后执行上一级的finally块,最后强制终止程序。
finally块后面得内容均不能执行。
5.结论
(1)try块中,没有发生异常,try->finally->后续代码;
(2)try块中,发生异常语句后面的代码不会执行;
(3)try块中,发生异常,如果被本级catch捕获,那么 本级catch块-->本级finally块-->后续代码;
(4)try块中,发生异常,如果被上级catch捕获,那么 本级finally块-->上级catch块-->上级finally块-->上级后续代码;
(5)try块中,发生异常,如果没有被任何级别catch捕获,那么 本级finally块-->上级finally块--->程序终止。
6 异常使用建议(仅供参考)
(1)发布的程序应该尽量避免因为没有catch到异常而被迫关闭,从而让用户觉得你的程序不健壮,所以至少要在最上级catch中捕获所有异常;
(2)需要清理资源的部分,尽量放入finally块,因为无论如何finally块总会被执行。