使用Dispose()方法

时间:2014-07-20 20:51:33

标签: c# timer dispose

为什么我看到"你好"在发布模式下将 timer.Dispose()添加到我的代码中的次数很多次。如果没有 timer.Dispose(),我会看到" Hello"一旦。谢谢。

using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static void Method(object state)
        {
            Console.WriteLine(state);
            GC.Collect();
        }

        static void Main()
        {
            var timer = new Timer(Method, "Hello", 0, 200);

            Console.ReadLine();
            timer.Dispose();
        }
    }
}

2 个答案:

答案 0 :(得分:3)

你看到它一次,因为垃圾收集器已经收集了计时器对象。

由于没有更多被称为“实时”的引用,垃圾收集器可以自由地进行。

在发布模式下,当没有附加调试器时,JITter会建立有关方法中局部变量使用位置的知识。一旦变量不再使用,如果该方法当前正在该点之下执行,则不再将其视为根。这样,垃圾收集器可以收集计时器对象。但是,在它可以这样做之前,它必须完成对象,它会破坏底层的计时器对象并阻止它执行。

在调试版本中,所有局部变量的范围都被人为地扩展为整个方法,因此如果在方法中放置断点,则可以检查变量,即使程序实际上不再需要该变量存在

当您添加对dispose的调用时,您延长了变量的生命周期,从而阻止了垃圾收集器收集您的计时器对象。

由于您在计时器事件处理程序方法中引发了垃圾收集,因此在这种情况下您可以自己销毁计时器。通过添加对Dispose的调用来扩展变量的生命周期时,垃圾收集器仍然作为计时器事件处理程序的一部分运行,但它还无法收集计时器,因此它会一直运行。

Hans Passant留下的答案比我上面的微薄尝试要好得多:

Understanding Garbage Collection in .NET

答案 1 :(得分:0)

我怀疑它是因为GC.Collecttimer对象仍然被引用到当前代码行之下时不会收集它。

在这种情况下,

timer.Dispose();的行为与GC.KeepAlive(timer);类似。

如果同时删除DisposeGC.Collect(),您将获得一些" Hello" s,然后GC将决定自行收集,而您#&# 39;不再有了。