我从阅读MSDN文档中了解到,IDisposable接口的"主要"用途是清理非托管资源.
对我来说,"非托管"意味着数据库连接,套接字,窗口句柄等等.但是,我已经看到了Dispose()实现该方法以释放托管资源的代码,这对我来说似乎是多余的,因为垃圾收集器应该照顾那对你而言.
例如:
public class MyCollection : IDisposable
{
private List<String> _theList = new List<String>();
private Dictionary<String, Point> _theDict = new Dictionary<String, Point>();
// Die, clear it up! (free unmanaged resources)
public void Dispose()
{
_theList.clear();
_theDict.clear();
_theList = null;
_theDict = null;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,这是否使得垃圾收集器可以使用的内存MyCollection比通常更快?
编辑:到目前为止,人们已经发布了一些使用IDisposable清理非托管资源(例如数据库连接和位图)的好例子.但是假设_theList在上面的代码中包含了一百万个字符串,并且你想现在释放那个内存,而不是等待垃圾收集器.上面的代码会实现吗?
以下是典型的配置模式示例:
public bool IsDisposed { get; private set; }
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!IsDisposed)
{
if (disposing)
{
//perform cleanup here
}
IsDisposed = true;
}
}
~MyObject()
{
Dispose(false);
}
Run Code Online (Sandbox Code Playgroud)
我理解dispose的作用,但是我不明白你为什么要在析构函数中调用dispose(false)?如果你看一下这个定义它什么都不会做,那么为什么有人会编写这样的代码呢?根本不打算从析构函数中调用dispose 是不是有意义?
根据文档(MSDN:链接),很明显在实现终结器时应该使用IDisposable模式.
但是,如果实现IDisposable(以便提供处理对象的确定性方法),您是否需要实现终结器?并且您没有任何非托管资源来清理?
在我看来,如果类只有托管资源,如果你不调用Dispose,那么托管资源将自动被GC清理,因此不需要实现终结器.我错了吗?
另外,如果我使用我的Dispose方法清理事件处理程序,该怎么办?由于Dispose不会自动被GC调用,我应该实现Finalizer,以确保事件处理程序无线连接吗?
所以我的理解是,每当使用实现IDisposable的类时,它的父级也需要实现IDisposable接口。(使用FileSystemWatcher的FileWatcher)
因此,在使用FileSystemWatcher时,处置FileSystemWatcher的正确方法是什么?我希望在关闭应用程序之前不处理/(监视)FileWatcher。
我会使用“负责任的所有者模式”吗(尝试/最终)还是其他?我的FileWatcher是否也应该实现IDisposable?我将无法使用using {},因为此fileWatcher应该在应用程序整个运行过程中监视文件的更改。处理这种情况的正确方法是什么?
public class FileWatcher : IFileWatcher
{
private FileSystemWatcher watcher;
public event EventHandler<EventArgs> SettingsChanged;
public FileWatcher(bool start)
{
this.RegisterForChanges();
}
public void OnChanged(object source, EventArgs e)
{
if (this.SettingsChanged != null)
{
this.SettingsChanged(source, new EventArgs());
}
}
private void RegisterForChanges()
{
/// more code here etc
...
this.watcher = new FileSystemWatcher
{
Path = directory,
NotifyFilter =
NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName,
Filter = fileName
};
// Add event handlers.
this.watcher.Changed += this.OnChanged;
// Begin …Run Code Online (Sandbox Code Playgroud)