Eas*_*ere 33 c# destructor idisposable using
我对学习C#(来自Java和C++背景)相当新,我对手动垃圾处理有疑问:是否有可能手动销毁C#中的对象?我知道IDisposable接口,但是假设我正在处理一个我没写过的类而且它没有实现它?它不会有一个.Dispose()方法,使和using { }超出,并且.Finalize始终为protected还是private这样,要么是不是一种选择.
(我只是想了解什么是可能在C#在这种情况下,我想,如果一切都失败了,我可以继承的假设ImNotDisposable类,以便它不实现IDisposable.)
Joe*_*orn 31
您不要手动销毁.Net对象.这就是托管环境的全部意义所在.
事实上,如果对象实际上是可以访问的,这意味着你有一个引用,你可以使用它来告诉GC要销毁哪个对象,收集该对象是不可能的.GC 永远不会收集任何仍可访问的对象.
你可以做的是打电话GC.Collect()强制一般收藏.但是,这几乎从来都不是一个好主意.
相反,最好只是假装任何不使用非托管资源且程序中任何其他对象无法访问的对象立即被销毁.我知道这不会发生,但在这一点上,对象只是一块内存,就像其他任何一样; 你不能收回它,它最终会被收集,所以你可能也死了.
最后一点关于IDisposable.您应该只将它用于包装非托管资源的类型:套接字,数据库连接,gdi对象等,以及偶尔的事件/委托订阅.
如果无法访问该对象,则可以调用GC.Collect()该对象并将其销毁.这个概念IDisposable与CLR无关,主要是用户代码实现执行额外的处理逻辑.在对象上调用Dispose()不会将对象本身从内存中释放出来,尽管它可以很好地处理此对象引用的任何资源.
我应该补充一点,虽然我所说的是一种实现这一目标的方法,但在99.9999%的应用程序中你永远不应该调用GC.Collect()它,因为它通常会降低应用程序的性能而不是改进它.
虽然您可以触发垃圾收集(您需要为所有代触发GC,因为您无法确定可终结对象所在的那一代),但您不一定强制完成特定对象.您只能依赖于有关垃圾收集器如何工作的假设.
更确切地说,由于终结发生在它自己的线程上,你应该在触发垃圾收集后调用WaitForPendingFinalizers.
GC.Collect(GC.MaxGeneration);
GC.WaitForPendingFinalizers();
Run Code Online (Sandbox Code Playgroud)
正如其他人所指出的,这实际上可能会损害您的应用程序的性能,因为不必要地调用GC可以将其他短期对象推向更高代,这些对象收集起来更昂贵并且收集频率更低.
一般来说,实现终结器(析构函数)并且不实现IDisposable的类是不受欢迎的.任何实现IDisposable的东西都应该调用它的终结器逻辑并且在垃圾收集中完成自定义.
Jeff Richter最近发布了一个很好的小技巧,用于在垃圾收集发生时收到通知.
Rico Mariani(MSFT)关于垃圾收集器基础知识和性能提示的另一篇精彩文章
你可以在要销毁的变量超出范围后强制垃圾收集器运行,但您通常不想这样做,因为如果让垃圾收集器自行完成工作,则会更高效。
可以使用GC.Collect强制进行垃圾回收,但不要这样做。在我作为 .NET 开发人员的 10 年里,我从未需要过它。
| 归档时间: |
|
| 查看次数: |
71462 次 |
| 最近记录: |