简体   繁体   English

使用Dispose()方法

[英]Using Dispose() method

Why I see "Hello" words many times when I add timer.Dispose() to my code in release mode. 为什么在释放模式下向我的代码中添加timer.Dispose()时会多次看到“ Hello”字样。 Without timer.Dispose() I see "Hello" once. 没有timer.Dispose(),只会看到“ Hello”一次。 Thanks. 谢谢。

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();
        }
    }
}

You see it once because the garbage collector has collected the timer object. 您只看到一次,因为垃圾收集器已经收集了计时器对象。

Since there are no more references to it that is considered "live" the garbage collector is free to do so. 由于没有更多的引用被认为是“实时的”,因此垃圾收集器可以自由地这样做。

In release mode, and when no debugger is attached, the JITter builds up knowledge of where local variables are used in a method. 在发布模式下,并且当没有连接调试器时,JITter会积累有关在方法中使用局部变量的知识。 Once a variable is no longer used, it is no longer considered to be a root if the method is currently executing below that point. 一旦不再使用变量,如果该方法当前在该点以下执行,则不再将其视为根。 As such, the garbage collector can collect the timer object. 这样,垃圾收集器可以收集计时器对象。 However, before it can do so it must finalize the object, which destroys the underlying timer object and stops it from executing. 但是,在这样做之前,它必须终结该对象,这将破坏基础计时器对象并使其停止执行。

In debug builds, the scope of all local variables are artificially extended to be the entire method, so that if you place a breakpoint in the method you can inspect variables, even if the program would no longer actually require that variable to exist. 在调试版本中,所有局部变量的范围都被人为地扩展为整个方法,因此,即使在程序不再实际上要求该变量存在的情况下,如果在方法中放置断点,也可以检查变量。

When you added the call to dispose, you extended the lifetime of the variable, and thus prevented the garbage collector from collecting your timer object. 当添加调用以处理时,您延长了变量的生存期,从而阻止了垃圾收集器收集您的计时器对象。

Since you provoke a garbage collection in the timer event handler method, you effectively destroy the timer yourself in this case. 由于您在计时器事件处理程序方法中引发了垃圾回收,因此在这种情况下,您可以有效地销毁计时器。 When you extended the lifetime of the variable by adding in the call to Dispose, the garbage collector still runs as part of your timer event handler, but it cannot yet collect the timer, so it keeps running. 当您通过添加对Dispose的调用来延长变量的生存期时,垃圾收集器仍作为计时器事件处理程序的一部分运行,但是它仍无法收集计时器,因此它将继续运行。

The answer left here by Hans Passant describes this much better than my meager attempt above: 汉斯·帕桑特(Hans Passant)在这里留下的答案比我上面的微薄尝试更好地描述了这一点:

Understanding Garbage Collection in .NET . 了解.NET中的垃圾回收

I suspect it's because GC.Collect will not collect the timer object when it's still referenced below the current line of code. 我怀疑这是因为GC.Collect仍在当前代码行下方引用时不会收集timer对象。

timer.Dispose(); is acting like GC.KeepAlive(timer); 就像GC.KeepAlive(timer); in this instance. 在这种情况下。

If you remove both the Dispose and the GC.Collect() , you will get a few "Hello"s, and then the GC will decide to collect by itself, and you'll get no more. 如果同时删除DisposeGC.Collect() ,则会得到一些“ Hello”,然后GC将决定自行收集,而您将一无所获。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM