我从阅读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在上面的代码中包含了一百万个字符串,并且你想现在释放那个内存,而不是等待垃圾收集器.上面的代码会实现吗?
C#2008
我一直在研究这个问题,我仍然对一些问题感到困惑.我的问题如下
我知道如果你处理非托管资源,你只需要一个终结器.但是,如果您使用托管资源来调用非托管资源,您是否仍需要实现终结器?
但是,如果您开发一个不直接或间接使用任何非托管资源的类,您是否可以实现IDisposable该类,以便您的类的客户端可以使用'using statement'?
是否可以接受实现IDisposable,以便您的类的客户端可以使用using语句?
using(myClass objClass = new myClass())
{
// Do stuff here
}
Run Code Online (Sandbox Code Playgroud)我在下面开发了这个简单的代码来演示Finalize/dispose模式:
public class NoGateway : IDisposable
{
private WebClient wc = null;
public NoGateway()
{
wc = new WebClient();
wc.DownloadStringCompleted += wc_DownloadStringCompleted;
}
// Start the Async call to find if NoGateway is true or false
public void NoGatewayStatus()
{
// Start the Async's download
// Do other work here
wc.DownloadStringAsync(new Uri(www.xxxx.xxx));
}
private void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
// …Run Code Online (Sandbox Code Playgroud)我何时在类上实现IDispose而不是析构函数?我读过这篇文章,但我仍然忽略了这一点.
我的假设是,如果我在一个对象上实现IDispose,我可以显式"破坏"它,而不是等待垃圾收集器这样做.它是否正确?
这是否意味着我应该总是在对象上显式调用Dispose?这有什么常见的例子?
在这个答案中我发现,
在代码中使用Dispose/Finalize模式时,清除Finalize方法中的非托管资源和Dispose方法中的托管资源.
后来我发现这篇关于敲定和处理的好文章,并对它们有了清晰的认识.本文有以下代码(第3页),用于解释概念:
class Test : IDisposable
{
private bool isDisposed = false;
~Test()
{
Dispose(false);
}
protected void Dispose(bool disposing)
{
if (disposing)
{
// Code to dispose the managed resources of the class
}
// Code to dispose the un-managed resources of the class
isDisposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
Run Code Online (Sandbox Code Playgroud)
但在此之下,出现了相同的注释(我在本问题开头所包含的注释).
Dispose/Finalize模式Microsoft建议您在使用非托管资源时实现Dispose和Finalize.然后,正确的顺序是开发人员调用Dispose.即使开发人员忽略了显式调用Dispose方法,也会在对象被垃圾回收时运行Finalize实现并仍然释放资源.Francesco Balena在他的博客中写道:只有当你的类型调用分配非托管资源(包括非托管内存)的非托管代码并返回最终必须用来释放资源的句柄时,才应使用Dispose/Finalize模式.只需处理和完成必须通过在处理或完成自己的成员之后调用父母的相应方法来链接到他们的父对象". 简单地说,在代码中使用Dispose/Finalize模式时,清除Finalize方法中的非托管资源和Dispose方法中的托管资源.
现在我又困惑了.在整篇文章和代码示例中,显示应释放非托管资源Dispose().但那个评论的相关性是什么?
编辑:
正如确认这一行:
简单地说,当在代码中使用Dispose/Finalize模式时,清理Finalize方法中的非托管资源和Dispose方法中的托管资源.
是错误的,我编辑了这个答案.
可能重复:
Finalize vs Dispose
嗨,
最近我在一次关于敲定和处置的采访中被问到了.何时使用它们以及垃圾收集器如何与它们相关.请分享链接,以更多地了解该主题.
请分享......
提前致谢.
我想知道在这些情况下何时调用析构函数,如果它是在主UI线程上调用它?
假设我有以下代码,什么时候会调用析构函数,它会等到我完成所有函数调用之后?
private void Foo()
{
MyObject myObj = new MyObject();
DoSomeFunThingsWithMyObject(myObj);
myObj = new MyObject(); //is the destructor for the first instance called now?
DoLongOminousFunctionality(myObj);
}
//Or will it be called after the DoLongOminousFunctionality?
Run Code Online (Sandbox Code Playgroud)
如果线程在myObj = new MyObject()中断,或者Destructor调用等待直到Thread空闲,那么这只是我感兴趣的东西.
谢谢你的信息.
我一直听到有关在终结器和Dispose()方法中放置代码来处理非托管资源的建议.我不明白的是,因为在GC发生时调用终结器所以我们可以在技术上假设它一直被调用.在那种情况下,为什么还要处理一个物体呢?我错过了什么吗?
我最近正在阅读一个论坛,看到这个评论:
所以,你看到你已经被骗了,相信'使用'语法将帮助你清理你的资源.哦,欢迎来到.NET开发.
这真让我吓坏了!在几乎所有情况下(特别是流),我几乎只使用.Dispose().没有人告诉我,"使用"是否有一些奇怪的事情?使用是好是坏还是无动于衷?