System.Threading.Timer在25-30次后停止

时间:2019-10-11 17:57:23

标签: c# multithreading timer

<U>

在我的C#应用​​程序中,计时器仅工作30次。之后停止。为什么,我不知道。哪里错了?

这是我的CheckLimit助手;

        var startTimeSpan = TimeSpan.Zero;
        var periodTimeSpan = TimeSpan.FromSeconds(5);

        var timer = new System.Threading.Timer((e) =>
        {
            limit = helper.CheckLimit();
        }, null, startTimeSpan, periodTimeSpan); 

1 个答案:

答案 0 :(得分:0)

我的赌注是乔恩(Jon)的建议,我将pla窃以为依据。

Timer Class (System.Threading)的doco包含以下注释。

  

只要您使用计时器,就必须保留对其的引用。与任何托管对象一样,如果没有对计时器的引用,则计时器将进行垃圾回收。计时器仍处于活动状态并不能阻止它被收集。

var timer建议您可能没有保持引用状态。您可以将其设置为对象的字段,该对象在应用程序的整个生命周期中都保持活动状态。

高级注释new System.Threading.Timer(TimerCallback callback)构造函数对this对象使用state,这使计时器在整个GC.Collect内都保持活动状态(请参阅下文)了解更多)。


示例

这是说明问题的完整示例。

输出

A
B
A
B
B
A
GC Collected
B
B
B

代码

using System;
using System.Threading.Tasks;

class TimerExperiment
{
    System.Threading.Timer timer; 
    public TimerExperiment() {
        StartTimer("A"); // Not keeping this timer
        timer = StartTimer("B"); // Keeping this timer
    }

    static System.Threading.Timer StartTimer(string name) {
        return new System.Threading.Timer(_ =>
        {
            Console.WriteLine($"{name}");
        }, null, dueTime: TimeSpan.Zero, period: TimeSpan.FromSeconds(1));
    }

}

class Program
{
    static async Task Main(string[] args)
    {
        var withTimers = new TimerExperiment();

        await Task.Delay(TimeSpan.FromSeconds(2));
        GC.Collect();
        Console.WriteLine("GC Collected");
        Console.ReadLine();
    }
}


浑水

System.Threading.Timer的{​​{1}}构造函数(不使用Timer(TimerCallback callback)的构造函数)对dueTime使用this,这意味着计时器将保留对自身的引用,这意味着它将在垃圾回收中幸免。

state

示例2

计时器'C'是使用public Timer(TimerCallback callback) { (...) TimerSetup(callback, this, (UInt32)dueTime, (UInt32)period, ref stackMark); } 创建的,并且一直运行。

输出

Timer(TimerCallback callback)

代码

A
B
C
A
B
C
GC Collected
B
C
C
B
B
C