我对处理感到困惑。我正在尝试让我的代码正确处理资源。所以我一直将我的类设置为IDisposable(使用Dispose方法),确保调用Dispose方法。
但是现在FXCop告诉我很多关于Disposing = false和调用Dispose(false)的东西。
我没有看到采用bool的Dispose方法。我需要制作一个吗?如果是这样,为什么?为什么不在处理时调用一个方法呢?
我在这里看到了一些代码:http://msdn.microsoft.com/en-us/library/ms244737.aspx,它展示了如何制作一个带有bool的Disposing方法。它表示它适用于本地和管理资源。 但我认为处理的全部内容仅适用于非托管资源。
此外,FXCop抱怨的是:
~OwnerDrawnPanel()
{
_font.Dispose();
}
它说:
CA1063:Microsoft.Design:修改'OwnerDrawnPanel .~ OwnerDrawnPanel()',使其调用 Dispose(false),然后返回。
但Font上没有Dispose(bool)(我能找到)。
为什么我需要Dispose(bool)?如果我这样做,为什么Font没有呢?因为它没有它,为什么FXCop要求我使用它?
感谢所有出色的答案。我想我现在明白了。这是
处置“非托管”资源分为两类:
Dispose(bool)用于区分两者:
答案 0 :(得分:8)
Dispose(bool)
是实施Finalize
和Dispose
清理非托管资源的模式,see this for detail
答案 1 :(得分:7)
Dispose(bool)
并非公开,这就是您在Font
上看不到的原因。
如果您班级的某些用户忘记在您的方法上调用Dispose,您将通过拨打Dispose(false)
中的Finalizer
来释放非托管资源 。
如果正确调用了IDispose,则调用托管资源上的Dispose,也处理非托管资源。
标志是区分这两种情况。
这是MSDN推荐的模式。
答案 2 :(得分:7)
IDisposable
提供了一个带签名的方法
public void Dispose()
Microsoft最佳做法(http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx)建议使用签名
制作第二个私有方法private void Dispose(bool)
您的公共Dispose方法和Finalizer应调用此私有Dispose方法以防止多次处理受管资源。
您可以通过在dispose方法中实现IDisposable和处理字体对象,或在类中创建Dispose(bool)
方法,并使终结器调用该方法来修复您获得的警告。
答案 3 :(得分:3)
FxCop说你应该实现像here所述的Disposable模式。请注意,您应not使用终结器来处理托管资源,例如_font
。终结器用于清理非托管资源。如果不在(子)类的Dispose方法中执行清理逻辑,它们将由垃圾收集器执行非确定性。
答案 4 :(得分:2)
另请注意,您需要在析构函数中执行任何操作很少。通常情况下,垃圾收集器都会处理所有事情。例如,在代码中,您不需要在_font
的析构函数中部署OwnerDrawnPanel
对象。由于GC正在清理面板,因此_font
也是如此,因为面板是唯一引用它的人,对吗?
通常,如果您拥有一次性对象,则只需在调用自己的Dispose
方法时将其丢弃。但析构函数中的 NOT 。当你的析构函数运行时,你可以打赌所有的聚合对象也都被清理了。
答案 5 :(得分:2)
你几乎不需要使用终结器。它们仅适用于直接包含非托管资源的类,而在.NET 2.0+中,它们应该包含在SafeHandle中。
答案 6 :(得分:2)
我认为Dispose(true)
将释放托管和非托管资源,因为我们不需要再次调用finalize,这就是我们在GC.SupressFinalize()
之后编写Dispose(true)
的原因。
我们在析构函数中调用Dispose(false)
来释放非托管资源,并且将由运行时而不是用户代码调用。
答案 7 :(得分:1)
同意Kumar,Dispose(bool disposing)
模式也记录在案on MSDN。区别不在托管和非托管资源之间,而是代码或运行时是否调用Dispose
。
答案 8 :(得分:0)
我发现了一篇关于正确实现IDispose接口的好文章:http://msdn.microsoft.com/en-us/library/ms244737(v=vs.80).aspx
答案 9 :(得分:0)
实施公开public void Dispose()
,protected virtual void Dispose(bool)
和~ClassName()
终结器的模式是最佳做法recommended by Microsoft,可以整齐地整理托管和清除代码非托管资源。
基本上,使用Disposable
类的代码应该调用Dispose()
,但如果没有,则终结符~ClassName()
将被Garbage调用使用集合,并根据其中的哪一个,将参数设置为Dispose(bool)
为true或false,在Dispose(bool)
中,只有在参数为true时才清理托管资源。
您收到的警告似乎特别建议您在finalize方法~ClassName()
中使用此练习。