为什么我们必须关闭finally {}块下的对象?

时间:2013-06-24 16:38:30

标签: c# .net try-catch

有人可以解释为什么#1方法比#2好吗?

1

try
{

}
catch
{
}
finally
{
reader.Close();  
dataStream.Close();
response.Close();
}

2

try
{

reader.Close();  
dataStream.Close();
response.Close();

}
catch
{
}

4 个答案:

答案 0 :(得分:7)

如果reader.Close()引发异常,您的两个选项都不会关闭dataStreamresponse

但是,在#2选项中,如果reader.Close()之前的代码引发异常,则不会关闭任何对象。在#1中,您至少可以保证即使其他内容引发异常,也会始终致电reader.Close()

一般情况下,任何带有Close()方法的对象也应该通过Close实现IDisposable.Dispose(),在这种情况下,我总是希望使用{ {1}}而不是以下任何一个选项:

using

这将强制所有对象都正确关闭,但更清晰。

答案 1 :(得分:4)

我更喜欢方法3

using(var reader = ...)
using(var dataStream = ...)
using(var response = ...)
{
    //...
}//all disposed (and implicitly closed) at the end of this scope

使用此构造,编译器将转换为大约:

var reader = ...;
var dataStream = ...;
var response = ...;
try
{
    //...
    //even if an error happens here
}
finally
{
   //this code still runs before control leaves this method.
   reader.Close();  
   dataStream.Close();
   response.Close();
}

答案 2 :(得分:0)

如果在关闭所有对象之前,try块中的任何位置发生异常,则不会关闭它们。 finally块允许您在try块中引发异常时执行清理。

正如其他人所提到的,using方法是我使用自己的代码的方式。编译器会将using转换为try{} finally{}块。请查看以下MSDN链接:http://msdn.microsoft.com/en-us/library/yh598w02.aspx

干杯。

答案 3 :(得分:0)

由于Try块旨在处理可能的故障,因此处理成功和不成功的情况非常重要。 Try块中的项可能会被调用,它们可能不会被调用 - 具体取决于发生故障的位置和位置。

通过将closure语句放入finally块,可以确保始终调用语句,无论Try部分是否成功。这样,即使发生了故障,也不会让读者,数据流和响应保持打开状态。