为什么有些人使用Finalize方法而不是Dispose方法?
在什么情况下你会使用Finalize方法而不是Dispose方法,反之亦然?
为什么有些人使用Finalize方法而不是Dispose方法?
在什么情况下你会使用Finalize方法而不是Dispose方法,反之亦然?
当前回答
c#中Finalize和Dispose方法的区别。
GC调用finalize方法来回收非托管资源(如文件操作、windows api、网络连接、数据库连接),但GC调用它的时间不固定。它是由GC隐式调用的,这意味着我们对它没有低级控制。
处理方法:当我们从代码中调用它时,我们对它有低级别的控制。我们可以在觉得不可用的时候回收非托管资源。我们可以通过实现IDisposal模式来实现这一点。
其他回答
Class instances often encapsulate control over resources that are not managed by the runtime, such as window handles (HWND), database connections, and so on. Therefore, you should provide both an explicit and an implicit way to free those resources. Provide implicit control by implementing the protected Finalize Method on an object (destructor syntax in C# and the Managed Extensions for C++). The garbage collector calls this method at some point after there are no longer any valid references to the object. In some cases, you might want to provide programmers using an object with the ability to explicitly release these external resources before the garbage collector frees the object. If an external resource is scarce or expensive, better performance can be achieved if the programmer explicitly releases resources when they are no longer being used. To provide explicit control, implement the Dispose method provided by the IDisposable Interface. The consumer of the object should call this method when it is done using the object. Dispose can be called even if other references to the object are alive.
注意,即使通过Dispose方法提供显式控制,也应该使用Finalize方法提供隐式清理。Finalize提供了一个备份,以防止程序员在调用Dispose失败时永久地泄漏资源。
我今天一直在寻找这个问题的答案。我将在这里分享我的经验。我的答案是基于这个联系,因为它有我所见过的最清楚的解释。
当您的对象访问非托管资源时,您必须手动释放这些资源。这可以通过IDisposable或finalizer来完成,这意味着它们都会释放非托管资源。
经验法则: 实现IDisposable以释放非托管资源,调用方代码必须调用Dispose方法。如果调用者忘记调用Dispose()方法,您仍然可以提供一个方法来释放那些非托管资源。第一个选择是使用安全句柄来包装非托管资源。第二个选项是定义终结器。在这种情况下,建议使用安全手柄。
我认为这种联系是对这个问题最明确的答案。我不知道为什么人们在网上对这个问题给出复杂的解释。这让我很困惑,直到我找到了那个联系。
这是我知道的最好的例子。
public abstract class DisposableType: IDisposable
{
bool disposed = false;
~DisposableType()
{
if (!disposed)
{
disposed = true;
Dispose(false);
}
}
public void Dispose()
{
if (!disposed)
{
disposed = true;
Dispose(true);
GC.SuppressFinalize(this);
}
}
public void Close()
{
Dispose();
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// managed objects
}
// unmanaged objects and resources
}
}
Finalize在该对象不再使用时由GC调用。
Dispose只是一个普通的方法,该类的用户可以调用它来释放任何资源。
如果用户忘记调用Dispose,如果类实现了Finalize,那么GC将确保它被调用。
正如我们所知,dispose和finalize都用于释放非托管资源。 但不同的是finalize使用两个周期来释放资源,而dispose使用一个周期。