定时器可自动获得垃圾收集的? [英] Can Timers get automatically garbage collected?

查看:127
本文介绍了定时器可自动获得垃圾收集的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当您使用定时将只需运行该程序的整个生命周期你需要参照保持他们$ p $被垃圾收集pvent他们?

When you use a Timer or a Thread that will just run for the entire lifetime of the program do you need to keep a reference to them to prevent them from being garbage collected?

请抛开事实,下面的程序可以有定时作为类的静态变量,这仅仅是一个玩具的例子来说明这个问题。

Please put aside the fact that the below program could have timer as a static variable in the class, this is just a toy example to show the issue.

public class Program
{
    static void Main(string[] args)
    {
        CreateTimer();

        Console.ReadLine();
    }

    private static void CreateTimer()
    {
        var program = new Program();

        var timer = new Timer();
        timer.Elapsed += program.TimerElapsed;
        timer.Interval = 30000;
        timer.AutoReset = false;
        timer.Enabled = true;
    }

    private void TimerElapsed(object sender, ElapsedEventArgs e)
    {
        var timerCast = (Timer)sender;

        Console.WriteLine("Timer fired at in thread {0}", GetCurrentThreadId());

        timerCast.Enabled = true;
    }

    ~Program()
    {
        Console.WriteLine("Program Finalized");
    }

    [DllImport("kernel32.dll")]
    static extern uint GetCurrentThreadId();
}

能定时器获得在上面的例子中收集的?我跑了一段时间,我从来没有得到一个例外,也没有消息说〜项目()被调用。

更新:我从这个问题发现(<一href=\"http://stackoverflow.com/questions/18136735/can-timers-get-automatically-garbage-collected#comment26561465_18136735\">thanks sethcran )的线程由CLR跟踪,但我还是想了解定时器答案。

UPDATE: I found out from this question (thanks sethcran) that threads are tracked by the CLR, but I still would like an answer about Timers.

推荐答案

如果您没有另行参考存储在某个地方这是只与System.Threading.Timer类的问题。它有几个构造函数重载,即采取的状态的对象的人是很重要的。在CLR关注该国的对象。只要它是某处引用,在CLR保持定时器在其定时器队列和定时器对象不会得到垃圾收集。大多数程序员将不使用的状态对象,MSDN文章肯定不能解释它的作用。

This is only a problem with the System.Threading.Timer class if you don't otherwise store a reference to it somewhere. It has several constructor overloads, the ones that take the state object are important. The CLR pays attention to that state object. As long as it is referenced somewhere, the CLR keeps the timer in its timer queue and the timer object won't get garbage collected. Most programmers will not use that state object, the MSDN article certainly doesn't explain its role.

System.Timers.Timer是System.Threading.Timer类的包装,使得它更容易使用。特别地,将使用该状态对象,并保持一个参考它只要定时器。

System.Timers.Timer is a wrapper for the System.Threading.Timer class, making it easier to use. In particular, it will use that state object and keep a reference to it as long as the timer is enabled.

请注意,在你的情况下,计时器的Enabled属性是假的,当它进入你消逝的事件处理程序,因为你有自动复位= FALSE。因此,定时器,只要它进入你的事件处理程序是符合回收。但是你通过引用的发送者远离麻烦的说法,需要设置启用回真。这使得抖动报告中提及这样你就不会有问题。

Note that in your case, the timer's Enabled property is false when it enters your Elapsed event handler because you have AutoReset = false. So the timer is eligible for collection as soon as it enters your event handler. But you stay out of trouble by referencing the sender argument, required to set Enabled back to true. Which makes the jitter report the reference so you don't have a problem.

要格外小心,经过的事件处理程序。该方法中抛出的任何异常都将没有诊断被吞噬。这也意味着你不会将启用回真。您必须使用的try / catch做一些合理的。如果你不打算刻意结束你的程序,至少,你需要让你的主程序知道的东西是不工作了。将启用在finally语句才能避免定时收集垃圾=真实的,但在一遍遍让你的程序抛出异常的风险。

Do be careful with the Elapsed event handler. Any exception thrown inside that method will be swallowed without a diagnostic. Which also means that you won't set Enabled back to true. You must use try/catch to do something reasonable. If you are not going to intentionally end your program, at a minimum you'll need to let your main program know that something isn't working anymore. Putting Enabled = true in a finally clause can avoid getting the timer garbage collected, but at the risk of having your program throw exceptions over and over again.

这篇关于定时器可自动获得垃圾收集的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆