【问题标题】:GC.KeepAlive() and System.Timers.TimerGC.KeepAlive() 和 System.Timers.Timer
【发布时间】:2013-02-18 21:52:20
【问题描述】:

我已经在类级别 declered System.Timers.Timer 对象并在构造函数中创建。在另一个方法中启动了计时器。

在经过的事件处理程序中启用属性设置为 false 并执行一些代码并再次启用设置为 true。

我收到每个间隔的已过事件。 问题是经过一段时间后才停止。

我怀疑计时器对象是由 GC 在已用事件处理程序 eventhadler 中将 moment enabled 属性设置为 false 时收集的。

所以我希望我的计时器对象设置为保持活动状态。

我应该在我的项目中哪里声明GC.KeepAlive(timer)

【问题讨论】:

    标签: c# garbage-collection


    【解决方案1】:

    如果定时器是在类级别声明的,它不会被 GC 自动收集,因为它不会超出范围。并且将 Enabled 设置为 false 不会导致您描述的行为。你的问题在别的地方。

    我怀疑您的事件处理程序中存在异常。 System.Timers.Timer 吞下事件处理程序中发生的异常,这意味着如果异常从事件处理程序中逃脱,您将永远不会知道它。

    我怀疑你的代码是这样写的:

    myTimer.Enabled = false;
    // do stuff here
    myTimer.Enabled = true;
    

    如果在“在这里做事”期间抛出异常,则异常会转义处理程序,计时器永远不会重新启用,并且计时器代码会吞下异常,因此您永远不会知道发生了什么事。

    你应该像这样编写你的事件处理程序:

    myTimer.Enabled = false;
    try
    {
        // do stuff here
    }
    catch (Exception ex)
    {
        // handle exceptions
    }
    finally
    {
        myTimer.Enabled = true;
    }
    

    您通常只想捕获特定的异常——那些您知道如何处理的异常。像上面那样捕获所有异常通常是不好的做法。

    【讨论】:

    • 我知道这是一个老问题,但我也有同样的问题,但我将代码包装在 try catch finally 中,正如这里建议的那样,它似乎仍然经常停止。还有什么可能导致这种情况?
    • @AdamWilson 副手,我想不出还有什么会导致这个问题,除非其他一些代码将Enabled 设置为false。我的建议是发布一个包含相关代码的问题。也许其他人会有一些见解。
    猜你喜欢
    • 2016-02-02
    • 1970-01-01
    • 2019-03-27
    • 1970-01-01
    • 1970-01-01
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多