已用时间上的 C# 计时器不调用方法
本文关键字:调用 方法 计时器 时间上 | 更新日期: 2023-09-27 18:31:22
下面的类来自.Net Windows服务。方法DoSomeDatabaseStuff在第一次启动时需要10分钟,但是当时间经过时,此方法不会再次被调用。
public class Test
{
public void Start()
{
DoSomeDatabaseStuff();
_oTimer = new Timer(60000);
_oTimer.Elapsed += OnTimeout;
_oTimer.AutoReset = true;
_oTimer.Start();
}
private void OnTimeout(object source, ElapsedEventArgs e)
{
DoSomeDatabaseStuff();
_oTimer = new Timer(60000);
_oTimer.Elapsed += OnTimeout;
_oTimer.AutoReset = true;
_oTimer.Start();
}
}
这段代码中有很多严重的问题:
- 如果 Start 方法
- 旨在成为服务的 OnStart() 方法,那么您永远无法启动该服务。 OnStart() 必须在 30 秒内完成。 只需初始化计时器,无需执行任何其他操作
- 在已用事件处理程序中创建另一个计时器是一个严重的错误。 事件处理程序现在将运行两次。 第二次调用后,它将运行三次。 诸如此类。 测试
- 程序不会测试代码在服务中的运行方式。 已用事件处理程序永远不会运行,因为在事件处理程序可以运行之前,测试已经完成。 这解释了你的观察
- 必须在已用事件处理程序中使用 try/catch。 如果您不这样做,那么任何异常都将在没有诊断的情况下被吞下。 System.Timers.Timer 类就是这样讨厌的,请改用 System.Threading.Timer 还解释了您的观察 结果
- 必须确保事件处理程序是可重入的。 当事件处理程序的先前调用仍然繁忙时,它可以再次运行,当任务花费超过一分钟时,就会发生这种情况。 这很少有好的结局。 设置 AutoReset = false 是避免此重入的简单方法,在事件处理程序结束时启动计时器备份以使其重复。
我在Windows服务中使用System.Threading.Timer
。
也许这也解决了你的问题,因为其他人也对Windows服务中的System.Timers.Timer
有问题:"我发现System.Timers.Timer
在我的Windows服务应用程序中不起作用。因此,我已切换到System.Threading.Timer
"
请参阅:Windows Service System.Timers.Timer not trigger
private void InitService()
{
//starts immediately, interval is in TimeSpan
this._oTimer = new System.Threading.Timer(
OnTimeout,
null,
TimeSpan.Zero,
TimeSpan.FromMinutes(10)
);
}
protected override void OnStart(string[] args)
{
InitService();
}
protected override void OnStop()
{
this._oTimer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
}
private void ImportTimer_Elapsed(Object state)
{
DoSomeDatabaseStuff();
}
程序在计时器运行之前结束。 Timer
在后台线程中工作,当主线程停止时,女巫将终止。
尝试
static void Main(string[] args)
{
Test t = new Test();
t.Start();
Console.ReadLine();
}
不要每次都创建新的计时器,而是尝试将 OnTimeout 处理程序设置为:
_oTimer.Stop();
DoSomeDatabaseStuff();
_oTimer.Start();
与方法 Start() 类似。