一次性System.Threading.Timer状态直到程序退出才最终确定

时间:2009-10-05 22:51:18

标签: .net multithreading timer

我可能会做一些蠢事,在这种情况下我道歉。我正在使用System.Threading.Timer类,并设置开关定时器,使用state对象传递控制信息。一切都按照我的预期工作,除了在程序退出之前状态对象没有最终确定。这个例子说明了我的意思。

class State
    : IDisposable
{
    public State()
    {
        Console.Out.WriteLine("State.State()");
    }
    ~State()
    {
        Console.Out.WriteLine("State.~State()");
    }

    void IDisposable.Dispose()
    {
        Console.Out.WriteLine("State.Dispose()");
    }
}


class Program
{
    public static void Callback(object obj)
    {
        Console.Out.WriteLine("entering Callback()");

        State state = (State)obj;

        // . . . // do stuff

        Console.Out.WriteLine("leaving Callback()");
    }


    public static void Main(string[] args)
    {
        Timer t = new Timer(Callback, new State(), 1000, Timeout.Infinite);

        Thread.Sleep(5000);

        t.Dispose();
        t = null;
        GC.Collect(10, GCCollectionMode.Forced); // prod GC to release "State"
        Console.Out.WriteLine("leaving Main()");
    }
}

这个输出是:

State.State()
entering Callback()
leaving Callback()
leaving Main()
State.~State()

由于我设置Timeout.Infinite时间来获取一次性计时器,因此一旦调度计时器,线程池不应该将其引用释放到状态对象,而不是等到程序结束,如图所示。我担心这会是一个微妙的内存泄漏。

请赐教。 : - )

1 个答案:

答案 0 :(得分:-2)

在C#中,只有在对象被垃圾收集和销毁时才会调用'finalize'或解构函数。在此之前,不会调用该函数。

在您的示例中,GC永远不需要运行,因为它的内存开销很小。

我想我不够具体,所以我不会概括发生的事情,而是指向MSDN文章解释行为:

http://msdn.microsoft.com/en-us/library/system.object.finalize%28VS.71%29.aspx

当对象变得“无法访问”时(通过垃圾收集,虽然不能保证它何时运行),或者当应用程序域被关闭时,会调用Finalize。