Effective C# Item 15: Utilize using and try/finally for Resource Cleanup
2006-10-16 09:10
519 查看
Effective C# Item 15: Utilize using and try/finally for Resource Cleanup
当我们使用非托管资源(unmanaged resources)类型时,应当使用IDisposable接口的Dispose()方法来释放资源。在.Net环境中,对非托管资源的回收不是系统的责任,我们必须自己调用Dispose()方法来释放资源。确保非托管资源会释放的最好方法是使用using或者try/finally。
所有的非托管资源类型都实现了IDisposable接口。另外当我们没有明确的释放资源,比如我们忘记了,C#还会防护性的通过创建终结器(finalizer)来释放资源。如果我们希望应用程序运行的更快时,就应当尽快释放一些不必要的资源。幸运的是在C#中有新的关键字来完成这项任务。我们先考虑下面的代码:
public void ExcuteCommand(string connectString, string commandString)
public void ExcuteCommand(string connectString, string commandString)
public void ExcuteCommand(string connectString, string commandString)
using(SqlConnection myConnection = new SqlConnection(connectString))
try
finally
//错误
using(string msg = "this is a message")
//错误
using(object obj = Factory.CreateResource)
object obj = Factory.CreateResource();
using(obj as IDisposable)
public void ExcuteCommand(string connectString, string commandString)
public void ExcuteCommand(string connectString, string commandString)
public void ExcuteCommand(string connectString, string commandString)
myConnection.Close();
这样做的确能够释放连接,但是并不是和Dispose()方法一样。Dispose()方法除了释放资源之外,还有其他的工作:它会通知垃圾收集器(Garbage Collector)这个对象的资源已经被释放了,而不必在终结器中进行重复的操作。Dispose()调用了GC.SuppressFinalize()方法,这个方法请求系统不要调用指定对象的终结器。而Close()不是这样的。使用Close()释放的对象虽然已经不必调用终结器,但是它还是存在于终结器的释放资源队列当中。Dispose()比Close()的工作做的更加彻底。
Dispose()并没有将对象移出内存。它为对象添加了一个释放资源的钩子(hook)。这就意味着我们可以对正在使用的对象使用Dispose(),我们应当小心这一点。
在C#中大部分的类型都不支持Dispose()。在超过1500种类型中只有100来种实现了IDispose接口。当我们使用实现了这个接口的对象时,我们应当在适当的时候使用using或try/finally块的方法来释放资源。
译自 Effective C#:50 Specific Ways to Improve Your C# Bill Wagner著
回到目录
P.S. 以下为个人想法:
Dispose()和Close()都是可以显示调用来释放资源。而Finalize()是受保护的,析构函数更是不知道什么时候会被执行。被Close()掉的对象是有可能再次复活的,比如SqlConnection,还可以通过Open()继续使用,好像是休眠状态。而被Dispose()掉的对象从理论上来说是不应当再复活了,因为我们在Dispose的同时应当告诉GC这个对象已经over了,以避免重复的对象清除工作。当然我们可以通过释放资源时获得其引用的诡异方法来继续访问对象,但是由于Dispose()调用GC.SuppressFinalize()方法免除终结,因此这些Dispose()掉又复活的对象的资源就再也不会自动被GC释放了。
public class DisposeClass : IDisposable
static void Main(string[] args)
static void Main(string[] args)
public class DisposeClass : IDisposable
public class ExtendDisposeClass : DisposeClass
{
~ExtendDisposeClass()
{
Console.WriteLine("destroyExtendDisposeClass object");
}
}
释放个资源可真是不简单啊...
当我们使用非托管资源(unmanaged resources)类型时,应当使用IDisposable接口的Dispose()方法来释放资源。在.Net环境中,对非托管资源的回收不是系统的责任,我们必须自己调用Dispose()方法来释放资源。确保非托管资源会释放的最好方法是使用using或者try/finally。
所有的非托管资源类型都实现了IDisposable接口。另外当我们没有明确的释放资源,比如我们忘记了,C#还会防护性的通过创建终结器(finalizer)来释放资源。如果我们希望应用程序运行的更快时,就应当尽快释放一些不必要的资源。幸运的是在C#中有新的关键字来完成这项任务。我们先考虑下面的代码:
public void ExcuteCommand(string connectString, string commandString)
public void ExcuteCommand(string connectString, string commandString)
public void ExcuteCommand(string connectString, string commandString)
using(SqlConnection myConnection = new SqlConnection(connectString))
try
finally
//错误
using(string msg = "this is a message")
//错误
using(object obj = Factory.CreateResource)
object obj = Factory.CreateResource();
using(obj as IDisposable)
public void ExcuteCommand(string connectString, string commandString)
public void ExcuteCommand(string connectString, string commandString)
public void ExcuteCommand(string connectString, string commandString)
myConnection.Close();
这样做的确能够释放连接,但是并不是和Dispose()方法一样。Dispose()方法除了释放资源之外,还有其他的工作:它会通知垃圾收集器(Garbage Collector)这个对象的资源已经被释放了,而不必在终结器中进行重复的操作。Dispose()调用了GC.SuppressFinalize()方法,这个方法请求系统不要调用指定对象的终结器。而Close()不是这样的。使用Close()释放的对象虽然已经不必调用终结器,但是它还是存在于终结器的释放资源队列当中。Dispose()比Close()的工作做的更加彻底。
Dispose()并没有将对象移出内存。它为对象添加了一个释放资源的钩子(hook)。这就意味着我们可以对正在使用的对象使用Dispose(),我们应当小心这一点。
在C#中大部分的类型都不支持Dispose()。在超过1500种类型中只有100来种实现了IDispose接口。当我们使用实现了这个接口的对象时,我们应当在适当的时候使用using或try/finally块的方法来释放资源。
译自 Effective C#:50 Specific Ways to Improve Your C# Bill Wagner著
回到目录
P.S. 以下为个人想法:
Dispose()和Close()都是可以显示调用来释放资源。而Finalize()是受保护的,析构函数更是不知道什么时候会被执行。被Close()掉的对象是有可能再次复活的,比如SqlConnection,还可以通过Open()继续使用,好像是休眠状态。而被Dispose()掉的对象从理论上来说是不应当再复活了,因为我们在Dispose的同时应当告诉GC这个对象已经over了,以避免重复的对象清除工作。当然我们可以通过释放资源时获得其引用的诡异方法来继续访问对象,但是由于Dispose()调用GC.SuppressFinalize()方法免除终结,因此这些Dispose()掉又复活的对象的资源就再也不会自动被GC释放了。
public class DisposeClass : IDisposable
static void Main(string[] args)
static void Main(string[] args)
public class DisposeClass : IDisposable
public class ExtendDisposeClass : DisposeClass
{
~ExtendDisposeClass()
{
Console.WriteLine("destroyExtendDisposeClass object");
}
}
释放个资源可真是不简单啊...
相关文章推荐
- Item 15:Utilize using and try/finally for Resource Cleanup
- Item 15: Utilize using and try/finally for Resource Cleanup(Effective C#)
- Effective C#之15:Utilize using and Try/finally for Resource Cleanup
- Utilize using and try/finally for Resource Cleanup
- 【转】Effective C# Item 15: Utilize using and try-finally
- Effective C# Item15:利用using和try/finally语句来清理资源
- Effective C# Item15:利用using和try/finally语句来清理资源
- 《Effective C#》Item 15:利用using和try-finally来释放资源
- 《Effective C#》Item 15:利用using和try-finally来释放资源
- C# Using与Try..Finally 语句(转)
- Using C# Yield for Readability and Performance
- C# using 与Try-catch-finally的区别和用法
- C# 使用Using和Try/Finally 进行资源清理
- Item 15: Provide access to raw resources in resource-managing classes.(Effective C++)
- Effective Java 3rd 条目9 try-with-resource优于try-finally
- Visual Studio Tools for Office: Using C# with Excel, Word, Outlook, and InfoPath
- C# using 与Try-catch-finally的区别和用法
- C# Using与Try..Finally 语句探究
- 15.使用using和try/finally来做资源清理
- EffectiveC#15--使用using和try/finally来做资源清理