【问题标题】:System.Timers.Timer enabled and GarbageCollectorSystem.Timers.Timer 启用和 GarbageCollector
【发布时间】:2013-02-17 10:21:11
【问题描述】:

在我的项目中,我创建了System.Timers.Timer 对象,并且间隔设置为 10 分钟。 每 10 分钟,我就会收到经过的事件。在这个事件处理程序中,我正在执行一些代码。

在执行此代码之前,我将Enabled 属性设置为等于false,因为如果处理程序的执行时间比下一个时间间隔长,则另一个线程将执行已逝事件。

这里的问题是Elapsed 事件突然停止。

我已经阅读了一些文章并怀疑设置为 false 垃圾收集器的时刻启用属性会释放计时器对象。

如果正确请告诉我解决方案。

下面是示例代码:

public class Timer1
{
    private static System.Timers.Timer aTimer;

    public static void Main()
    {
        // Create a timer with a ten second interval.
        aTimer = new System.Timers.Timer(10000);

        // Hook up the Elapsed event for the timer.
        aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);

        // Set the Interval to 10min.
        aTimer.Interval = 600000;
        aTimer.Enabled = true;

        Console.WriteLine("Press the Enter key to exit the program.");
        Console.ReadLine();
    }

    private static void OnTimedEvent(object source, ElapsedEventArgs e)
    {
        aTimer.Enabled = false;

        // excutes some code

        aTimer.Enabled = true;
    }
}

【问题讨论】:

标签: c# .net timer garbage-collection


【解决方案1】:

由于您的类中有一个字段指向您的计时器对象,因此 GC 不会收集计时器对象。

但是您的代码可能会引发异常,这会阻止Enabled 属性再次变为真。为了防止这一点,你应该使用finally 块:

private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
    aTimer.Enabled = false;
    try
    {
        // excutes some code
    }
    catch(Exception ex)
    {
        // log the exception and possibly rethrow it
        // Attention: never swallow exceptions!
    }
    finally
    {
        aTimer.Enabled = true;
    }
}

【讨论】:

【解决方案2】:

您可以设置同步对象,在这种情况下,经过的只会发生在 该对象的所有者线程,没有并发。 这里发布了一个类似的问题: Do C# Timers elapse on a separate thread?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多