<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);
答案 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
计时器'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