在这个答案中我发现,
在代码中使用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方法中的托管资源.
是错误的,我编辑了这个答案.
我知道Dispose()用于非托管资源,并且在不再需要资源时不应该等待垃圾收集器完成对象.
但是,在处理对象时,它会抑制垃圾收集器的完成(GC.SuppressFinalize(this);在下面的代码中).这意味着如果对象包含托管资源,我们也必须照顾它,因为垃圾收集器不会清理它.
在下面的示例代码中(来自MSDN),"Component"是一个托管资源,我们为此资源调用dispose()(component.Dispose()).我的问题是,我们如何为作为托管资源的Component类实现此方法?我们应该使用像Collect()这样的东西来捅垃圾收集器来清理这部分吗?
任何想法将不胜感激.谢谢.
以下是我正在查看的代码来自MSDN:
using System;
using System.ComponentModel;
// The following example demonstrates how to create
// a resource class that implements the IDisposable interface
// and the IDisposable.Dispose method.
public class DisposeExample
{
// A base class that implements IDisposable.
// By implementing IDisposable, you are announcing that
// instances of this type allocate scarce resources.
public class MyResource: IDisposable
{
// Pointer to an external unmanaged resource.
private IntPtr handle;
// Other managed resource this class uses. …Run Code Online (Sandbox Code Playgroud) 我一直在研究标准的 Dispose 模式,我只是想知道我需要写什么来释放托管资源?如果这些资源已经“管理”了,那么我肯定不需要做任何事情。
如果是这种情况,并且我的类不包含任何非托管资源(因此不需要由 GC 完成),那么我是否只需要在我的 Dispose 方法中取消完成?:-
public void Dispose()
{
GC.SuppressFinalize(this);
}
Run Code Online (Sandbox Code Playgroud)
所以假设这是我的课程:
public sealed class MyClass : IDisposable
{
IList<MyObject> objects; // MyObject doesn't hold any unmanaged resource
private bool _disposed;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!_disposed)
{
// do I need to set the list to null and
// call Dispose on each item in the list?
if (disposing)
{
foreach (var o in objects)
o.Dispose();
objects = …Run Code Online (Sandbox Code Playgroud) 我知道实施配置模式的一般准则警告不要实现虚拟Dispose().但是,大多数情况下,我们只使用类中的托管资源,因此完整的部署模式似乎有点过分 - 即我们不需要终结器.在这种情况下,Dispose()在基类中使用虚拟是否可以?
考虑这个简单的例子:
abstract class Base : IDisposable
{
private bool disposed = false;
public SecureString Password { get; set; } // SecureString implements IDisposable.
public virtual void Dispose()
{
if (disposed)
return;
if (Password != null)
Password.Dispose();
disposed = true;
}
}
class Sub : Base
{
private bool disposed = false;
public NetworkStream NStream { get; set; } // NetworkStream implements IDisposable.
public override void Dispose()
{
if (disposed)
return;
if …Run Code Online (Sandbox Code Playgroud) 我已经看过像这样的问题,甚至我发现了很多,其中任何一个都为我提出了这个问题.
我们假设我有这个代码:
public class SuperObject : IDisposable
{
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) { }
}
Run Code Online (Sandbox Code Playgroud)
protected virtual void Dispose(bool)上SuperObject?因为那里真的没有什么可以处理的.public interface ICustom : IDisposable { }
Run Code Online (Sandbox Code Playgroud)
public class Custom : ICustom
{
public SuperObject Super { get; protected set; }
public Custom()
{
Super = new SuperObject();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public virtual void Dispose(bool disposing)
{
if (!disposing) return;
if (Super != null) …Run Code Online (Sandbox Code Playgroud)