C# System.Threading.Timer在25-30次后停止
在我的C#应用程序中,计时器只工作30次。然后停止。为什么,我不知道。哪里错了 这是我的支票限额助手C# System.Threading.Timer在25-30次后停止,c#,multithreading,timer,C#,Multithreading,Timer,在我的C#应用程序中,计时器只工作30次。然后停止。为什么,我不知道。哪里错了 这是我的支票限额助手 var startTimeSpan = TimeSpan.Zero; var periodTimeSpan = TimeSpan.FromSeconds(5); var timer = new System.Threading.Timer((e) => { limit = helper.CheckLi
var startTimeSpan = TimeSpan.Zero;
var periodTimeSpan = TimeSpan.FromSeconds(5);
var timer = new System.Threading.Timer((e) =>
{
limit = helper.CheckLimit();
}, null, startTimeSpan, periodTimeSpan);
我打赌乔恩的建议是正确的,我将把它抄袭成一个答案 的文档包含以下注释 只要使用计时器,就必须保留对它的引用。与任何托管对象一样,当没有对计时器的引用时,计时器将接受垃圾收集。计时器仍处于活动状态这一事实并不妨碍对其进行收集
var timer
表明您可能没有保持引用处于活动状态。您可以将其设置为对象的字段,该字段在应用程序的整个生命周期内保持活动状态
高级说明:新系统.线程.计时器(TimerCallback回调)
构造函数将此
用于状态
对象,这将使计时器在整个GC.Collect
过程中保持活动状态(请参阅下文了解更多信息)
例子 下面是一个完整的例子来说明这个问题 输出 代码
浑水
System.Threading.Timer
的Timer(TimerCallback回调)
构造函数(不使用dueTime
和其他构造函数的构造函数)将此
用于状态
,这意味着计时器将保留对自身的引用,这意味着它将在垃圾收集中生存
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();
}
}
例2
计时器“C”是使用Timer(TimerCallback回调)
创建的,它一直在运行
输出
代码
你能分享周围的代码吗?特别是
helper.CheckLimit()
I共享,谢谢。var timer在哪里?在某些方法中?您是否保持对计时器的引用处于活动状态,以确保它未被垃圾收集?从文档中可以看出:只要使用计时器,就必须保留对它的引用。与任何托管对象一样,当没有对计时器的引用时,计时器将接受垃圾收集。计时器仍处于活动状态这一事实并不妨碍对其进行收集。您如何知道计时器已停止工作?您是否有一些代码正在检查以确保实际调用了回调?您能给我一些示例代码吗?因为我是C#的新手,是的,当我回到电脑前,我会破解一些示例代码。
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();
}
}
public Timer(TimerCallback callback)
{
(...)
TimerSetup(callback, this, (UInt32)dueTime, (UInt32)period, ref stackMark);
}
A
B
C
A
B
C
GC Collected
B
C
C
B
B
C
class TimerExperiment
{
System.Threading.Timer timerB;
public TimerExperiment()
{
StartTimer("A"); // Not keeping this timer
timerB = StartTimer("B"); // Keeping this timer
StartTimer2("C"); // Not keeping this timer
}
static System.Threading.Timer StartTimer(string name) {
return new System.Threading.Timer(_ =>
{
Console.WriteLine($"{name}");
}, null, dueTime: Delay(name), period: TimeSpan.FromSeconds(1));
}
static System.Threading.Timer StartTimer2(string name)
{
//Create the timer using the constructor which only takes the callback
var t = new System.Threading.Timer( _ => Console.WriteLine($"{name}"));
t.Change(dueTime: Delay(name), period: TimeSpan.FromSeconds(1));
return t;
}
static TimeSpan Delay(string name)
=> TimeSpan.FromMilliseconds(Convert.ToInt64(name[0])*10);
}
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();
}
}