c#

位置:IT落伍者 >> c# >> 浏览文章

C#清理非托管对象[2]


发布日期:2020年05月20日
 
C#清理非托管对象[2]

public class MyDerivedResource: MyResourceRelease

{

private bool _disposed = false;

protected override void Dispose(bool isDisposing)

{

if(_disposed)

{

return;

}

try

{

if(isDisposing)

{

//释放托管资源

}

//释放非托管资源

_disposed = true;

}

finally

{

baseDispose(isDisposing);

}

}

}

这样可以确保释放继承链上所有对象的引用资源在整个继承层次中传播Dispose模式

那用Dispose方式非托管资源就是最好的方法了吗?

其实不然因为类型实现了IDispose接口这个类的使用者必须显示调用Dispose方法或者在创建该类型对象的时候使用using关键 字对于一些粗心的使用者可能会忘记调用Dispose方法或者没有使用using关键字这样就导致了非托管资源没有释放的后果

最佳方案

同时实现终结器和Dispose方式这样对于细心的使用者直接显示调用Dispose方法会提高垃圾回收的性能对于粗心的使用者虽然忘记了调用Dispose方法但也不至于使得非托管资源得不到释放

注意这里用到了GC SuppressFinalize(this)方法

代码如下:

public class MyResourceRelease: IDisposable

{

~MyResourceRelease()

{

Dispose(false);

}

/// 保证资源只用释放一次

private bool _alreadyDisposed = false;

/// 用来判断释放资源的类别(托管和非托管)

protected virtual void Dispose(bool isDisposing)

{

if(_alreadyDisposed)

{

return;

}

if(isDisposing)

{

//释放托管资源

}

//释放非托管资源

_alreadyDisposed = true;

}

public void Dispose()

{

Dispose(true);

//阻止GC把该对象放入终结器队列

GCSuppressFinalize(this);

}

}

[] []

               

上一篇:怎样保护你的.NET程序

下一篇:C#清理非托管对象[1]