C# Timer on Elapsed Time 不调用方法

标签 c# .net multithreading .net-4.0 timer

以下类来自 .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 秒内完成。只需初始化定时器,不要做任何其他事情
  • 在 Elapsed 事件处理程序中创建另一个计时器是一个严重的错误。您的事件处理程序现在将运行两次。第二次调用后,它将运行三次。等等。
  • 您的测试程序不会测试代码在服务中的运行方式。 Elapsed 事件处理程序将永远不会运行,因为测试将在您的事件处理程序运行之前完成。这解释了你的观察
  • 必须在 Elapsed 事件处理程序中使用 try/catch。如果你不这样做,那么任何异常都将在没有诊断的情况下被吞噬。 System.Timers.Timer 类很讨厌,改用 System.Threading.Timer 也解释了您的观察
  • 必须确保您的事件处理程序是可重入的。它可以在事件处理程序的先前调用仍处于繁忙状态时再次运行,当任务花费超过一分钟时会发生这种情况。这很少有好结果。设置 AutoReset = false 是避免这种重新进入的简单方法,在事件处理程序结束时重新启动计时器以使其重复。

关于C# Timer on Elapsed Time 不调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18786333/

相关文章:

c# - ADFS : Acquiring token with PromptBehavior. 自动

c# - DynamicObject - 根据参数值调用方法

.net - 如何模拟此应用程序挂起方案?

java - 始终调用 Thread.currentThread().interrupt();捕获 InterruptedException 时?

c# - 计算多个线程中的东西

c# - 禁用.NET中Treeview中根节点的折叠事件

c# - FFI 的 size_t 兼容类型

C# Flatten 嵌套对象

c# - 为什么在 WCF 中使用 LocalChannel 时执行序列化?

c# - 在 .NET 中获取文件类型