为什么在Dispose内部要调用GC.SuppressFinalize(true)?

sangsang28 2013-08-29 03:33:58
我看到很多实现public void Dispose()的代码都是这样的:

Dispose(true);//自定义了一个private的Dispose(bool)函数
GC.SuppressFinalize(true);//这个不调用又会怎么样呢?

问题: 在Dispose函数内部一定要调用GC.SuppressFinalize吗?
如果一定要调用,那么传入true和传入false会有什么不同的效果么?
...全文
622 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
麻子 2015-11-24
  • 打赏
  • 举报
回复
引用 3 楼 sjyforg 的回复:
GC.SuppressFinalize(this); 一般是这么写的吧。 就是告诉垃圾回收器不要调用指定对象的Dispose方法,因为之前Dispose(true);已经做过了。 防止两次执行。
不是不要调用Dispose吧,应该是不要调用Finalize吧。
threenewbee 2013-08-29
  • 打赏
  • 举报
回复
对于这种控制台的小程序,有时候无论你怎么写,包括写GC.Collect(),还是在进程退出的时候才回收。
threenewbee 2013-08-29
  • 打赏
  • 举报
回复
引用 5 楼 u011858831 的回复:
[quote=引用 4 楼 yqb_6280180 的回复:] msdn上是这么解释的该方法在对象头中设置一个位,系统在调用终结器时将检查这个位。obj 参数应为此方法的调用方。实现 IDisposable 接口的对象可以从 IDisposable.Dispose 方法调用此方法,以防止垃圾回收器对不需要终止的对象调用 Object.Finalize。也就是向上楼说的防止多次调用Object.Finalize吧 节约性能 public void Dispose() { Dispose(true); // This object will be cleaned up by the Dispose method. // Therefore, you should call GC.SupressFinalize to // take this object off the finalization queue // and prevent finalization code for this object // from executing a second time. GC.SuppressFinalize(this); }
我写了下面这个小程序:

    public class b : IDisposable
    {
        public int i;
        public b() { Console.WriteLine("ctor"); }
        ~b() { Console.WriteLine("dtor"); }
        public void Dispose()
        {
            Console.WriteLine("Dispose");
            GC.SuppressFinalize(true);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            b objb = new b { i = 2 };
            using (objb)
            {
                Console.WriteLine("using");
            }
            Console.WriteLine("after using");
        }
    }
运行输出是:

ctor
using
Dispose
after using
dtor
Press any key to continue . . .
如果我把Suppress的参数从true改成false:

GC.SuppressFinalize(false);
发现结果还是一样。我的疑惑是,既然SuppressFinalize(false)了,那么是不是应该在Dispose()函数的末尾,也就是using块结束的时候,调用b.Finalize()也就是~b()。因此应该是先打印 dtor 再打印 after using 可是事实上是,现在的输出仍然是:

ctor
using
Dispose
after using
dtor
Press any key to continue . . .
看起来这个Suppress(false)没有起到作用啊? 还是我对于Dispose/using/Finalize的理解有误区? 上面这个小程序是VC#2012上编译执行的 请指教![/quote] 不是啊,只是通知GC去回收,不是说立刻去回收。
sangsang28 2013-08-29
  • 打赏
  • 举报
回复
自己再顶一下!
sangsang28 2013-08-29
  • 打赏
  • 举报
回复
引用 4 楼 yqb_6280180 的回复:
msdn上是这么解释的该方法在对象头中设置一个位,系统在调用终结器时将检查这个位。obj 参数应为此方法的调用方。实现 IDisposable 接口的对象可以从 IDisposable.Dispose 方法调用此方法,以防止垃圾回收器对不需要终止的对象调用 Object.Finalize。也就是向上楼说的防止多次调用Object.Finalize吧 节约性能 public void Dispose() { Dispose(true); // This object will be cleaned up by the Dispose method. // Therefore, you should call GC.SupressFinalize to // take this object off the finalization queue // and prevent finalization code for this object // from executing a second time. GC.SuppressFinalize(this); }
我写了下面这个小程序:

    public class b : IDisposable
    {
        public int i;
        public b() { Console.WriteLine("ctor"); }
        ~b() { Console.WriteLine("dtor"); }
        public void Dispose()
        {
            Console.WriteLine("Dispose");
            GC.SuppressFinalize(true);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            b objb = new b { i = 2 };
            using (objb)
            {
                Console.WriteLine("using");
            }
            Console.WriteLine("after using");
        }
    }
运行输出是:

ctor
using
Dispose
after using
dtor
Press any key to continue . . .
如果我把Suppress的参数从true改成false:

GC.SuppressFinalize(false);
发现结果还是一样。我的疑惑是,既然SuppressFinalize(false)了,那么是不是应该在Dispose()函数的末尾,也就是using块结束的时候,调用b.Finalize()也就是~b()。因此应该是先打印 dtor 再打印 after using 可是事实上是,现在的输出仍然是:

ctor
using
Dispose
after using
dtor
Press any key to continue . . .
看起来这个Suppress(false)没有起到作用啊? 还是我对于Dispose/using/Finalize的理解有误区? 上面这个小程序是VC#2012上编译执行的 请指教!
yqb_last 2013-08-29
  • 打赏
  • 举报
回复
msdn上是这么解释的该方法在对象头中设置一个位,系统在调用终结器时将检查这个位。obj 参数应为此方法的调用方。实现 IDisposable 接口的对象可以从 IDisposable.Dispose 方法调用此方法,以防止垃圾回收器对不需要终止的对象调用 Object.Finalize。也就是向上楼说的防止多次调用Object.Finalize吧 节约性能 public void Dispose() { Dispose(true); // This object will be cleaned up by the Dispose method. // Therefore, you should call GC.SupressFinalize to // take this object off the finalization queue // and prevent finalization code for this object // from executing a second time. GC.SuppressFinalize(this); }
申江渔夫 2013-08-29
  • 打赏
  • 举报
回复
GC.SuppressFinalize(this); 一般是这么写的吧。 就是告诉垃圾回收器不要调用指定对象的Dispose方法,因为之前Dispose(true);已经做过了。 防止两次执行。
sangsang28 2013-08-29
  • 打赏
  • 举报
回复
引用 1 楼 WM_JAWIN 的回复:
dispose告诉这个实体:哥不要你了,你可以去死了。 GC.SuppressFinalize(true); 这就是告诉系统,看到死尸了,让他去清理一下
这个SuppresFinalize我的里面是不要Finalize,也就是不要清理啊
WM_JAWIN 2013-08-29
  • 打赏
  • 举报
回复
dispose告诉这个实体:哥不要你了,你可以去死了。 GC.SuppressFinalize(true); 这就是告诉系统,看到死尸了,让他去清理一下

110,499

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧