Why should we call SuppressFinalize when we don#39;t have a destructor(当我们没有析构函数时为什么要调用 SuppressFinalize)
问题描述
我有几个问题我无法得到正确答案.
I have few Question for which I am not able to get a proper answer .
1) 当我们没有析构函数时,为什么要在 Dispose 函数中调用 SuppressFinalize.
1) Why should we call SuppressFinalize in the Dispose function when we don't have a destructor .
2) Dispose 和 finalize 用于在对象被垃圾回收之前释放资源.无论是托管资源还是非托管资源,我们都需要释放它,那么为什么我们需要在 dispose 函数中添加一个条件,当我们从 IDisposable:Dispose 调用这个被覆盖的函数时说 pass 'true' 并在从 finalize 调用时传递 false .
2) Dispose and finalize are used for freeing resources before the object is garbage collected. Whether it is managed or unmanaged resource we need to free it , then why we need a condition inside the dispose function , saying pass 'true' when we call this overridden function from IDisposable:Dispose and pass false when called from a finalize.
请看下面我从网上复制的代码.
See the below code I copied from net.
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);
}
}
如果我删除布尔受保护的 Dispose 函数并实现如下所示.
what if I remove the boolean protected Dispose function and implement the as below.
class Test : IDisposable
{
private bool isDisposed = false;
~Test()
{
Dispose();
}
public void Dispose()
{
// Code to dispose the managed resources of the class
// Code to dispose the un-managed resources of the class
isDisposed = true;
// Call this since we have a destructor . what if , if we don't have one
GC.SuppressFinalize(this);
}
}
推荐答案
我在这里有点冒险,但是......大多数人不需要需要成熟的 dispose 模式.在直接访问非托管资源(通常通过 IntPtr
)和继承方面,它的设计是可靠的.大多数情况下,实际上都不需要这些.
I'm going out on a limb here, but... most people don't need the full-blown dispose pattern. It's designed to be solid in the face of having direct access to unmanaged resources (usually via IntPtr
) and in the face of inheritance. Most of the time, neither of these is actually required.
如果您只是持有对实现 IDisposable
的其他东西的引用,那么您几乎可以肯定不需要终结器 - 直接持有资源的任何东西都负责处理它.你可以这样做:
If you're just holding a reference to something else which implements IDisposable
, you almost certainly don't need a finalizer - whatever holds the resource directly is responsible for dealing with that. You can make do with something like this:
public sealed class Foo : IDisposable
{
private bool disposed;
private FileStream stream;
// Other code
public void Dispose()
{
if (disposed)
{
return;
}
stream.Dispose();
disposed = true;
}
}
请注意,这不是线程安全的,但这可能不会成为问题.
Note that this isn't thread-safe, but that probably won't be a problem.
由于不必担心子类直接持有资源的可能性,您不需要抑制终结器(因为没有终结器) - 并且您不需要提供子类自定义处置的方法任何一个.没有继承,生活更简单.
By not having to worry about the possibility of subclasses holding resources directly, you don't need to suppress the finalizer (because there isn't one) - and you don't need to provide a way of subclasses customising the disposal either. Life is simpler without inheritance.
如果您确实需要允许不受控制的继承(即您不愿意打赌子类会有非常特殊的需求),那么您需要采用完整的模式.
If you do need to allow uncontrolled inheritance (i.e. you're not willing to bet that subclasses will have very particular needs) then you need to go for the full pattern.
请注意,使用 .NET 2.0 中的 SafeHandle
,您需要自己的终结器比在 .NET 1.1 中的情况更少.
Note that with SafeHandle
from .NET 2.0, it's even rarer that you need your own finalizer than it was in .NET 1.1.
首先要解决您关于为什么存在 disposing
标志的观点:如果您在终结器中运行,则您引用的其他对象可能已经终结.你应该让他们自己清理,你应该只清理你直接拥有的资源.
To address your point about why there's a disposing
flag in the first place: if you're running within a finalizer, other objects you refer to may already have been finalized. You should let them clean up themselves, and you should only clean up the resources you directly own.
这篇关于当我们没有析构函数时为什么要调用 SuppressFinalize的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:当我们没有析构函数时为什么要调用 SuppressFinalize
基础教程推荐
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01
- c# Math.Sqrt 实现 2022-01-01
- SSE 浮点算术是否可重现? 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- 如何激活MC67中的红灯 2022-01-01
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01
- MS Visual Studio .NET 的替代品 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01
- rabbitmq 的 REST API 2022-01-01