Pad*_*eep 54 .net c# idisposable
我有一个有一些非托管资源的类.我的类实现IDisposable
接口并释放方法中的非托管资源Dispose()
.我是否必须调用该Dispose()
方法或以某种方式自动调用?垃圾收集器会调用它吗?
And*_*bel 64
Dispose()
不会自动调用.如果有终结器,它将自动调用.实现IDisposable
为类的用户提供了一种方法,可以尽早释放资源,而不是等待垃圾收集器.
客户端的首选方法是使用using
处理自动调用的语句,Dispose()
即使存在异常.
正确实施IDisposable
是:
class MyClass : IDisposable
{
private bool disposed = false;
void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(!disposed)
{
if(disposing)
{
// Manual release of managed resources.
}
// Release unmanaged resources.
disposed = true;
}
}
~MyClass() { Dispose(false); }
}
Run Code Online (Sandbox Code Playgroud)
如果类的用户调用Dispose()
清理直接进行.如果对象被垃圾收集器捕获,则调用Dispose(false)
进行清理.请注意,从终结器(~MyClass
方法)调用时,托管引用可能无效,因此只能释放非托管资源.
如果在using
语句中实例化对象,则在代码退出using
块时为您调用Dispose()
using(var myObject = new MyDisposableObject())
{
blah();
} // Dispose() is called here (or whenever the code exits the block)
Run Code Online (Sandbox Code Playgroud)
如果你不使用using
,则由你(调用代码)通过明确调用Dispose()来处理你的对象.
此外,您(MyObject的实现者)可以添加对终结器的支持,以防您的调用者不调用Dispose().更多信息在这里.
您将不得不手动调用此方法,也许(假设“MyClass”实现“IDisposable”)在类似的构造中
using(var myclass = new MyClass())
{
// do something with myclass
}
// now 'myclass'is Disposed
Run Code Online (Sandbox Code Playgroud)
在C# 8.0 中,您可以编写如下语句:
using var myclass=new MyClass();
Run Code Online (Sandbox Code Playgroud)
并且“myclass”将在范围结束时自动处理。
该using
语句的优点(与显式调用 Dispose() 相比)是Dispose()
无论您如何退出此块都会调用它:通过运行越过末尾、遇到return
语句或抛出异常。
要确保正确处理资源,您需要在析构函数(终结器)中实现IDisposable
和调用Dispose
.
class Foo : IDisposable
{
private bool m_disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~Foo()
{
Dispose(false);
}
protected void Dispose(bool disposing)
{
if (!m_disposed)
{
if (disposing)
{
//release managed resources
}
//release unmanaged resources
m_disposed = true;
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
43074 次 |
最近记录: |