【问题标题】:System.Threading.Timer not firing after some timeSystem.Threading.Timer 一段时间后未触发
【发布时间】:2011-04-07 20:14:13
【问题描述】:

我有一个 Windows 服务应用程序。并通过在控制台模式下运行来调试它。

这里http://support.microsoft.com/kb/842793 据说 Timers.Timer 有一个错误并且没有在 Windows 服务中触发。解决方法是使用 Threading.Timer 而且这篇文章是针对.NET 1.0 和 1.1 的

我正在使用 .NET 4,但一段时间后 Threading.Timer 也不会触发。那么这可能是什么原因呢? 您能提出什么解决方法?

谢谢,

最好的问候

编辑:我将计时器从 Threading.Timer 更改为 Timers.Timer,它可以正常工作。

【问题讨论】:

  • 我认为加快解决这个问题的一个好方法是发布 Timer 初始化和启动代码。
  • 我正在从本机 win32 dll 调用一个函数,但它在其他线程上

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


【解决方案1】:

您是否在某处保留对计时器的引用以防止它被垃圾收集?

来自the docs

只要你使用定时器,你 必须保留对它的引用。与 任何托管对象,Timer 都是主题 有垃圾收集 没有引用它。一个事实 定时器仍处于活动状态不会阻止 它不会被收集。

【讨论】:

  • @AFgone:但在哪里?您有多确定它没有被垃圾收集?
【解决方案2】:

您的计时器对象超出范围并在一段时间后被垃圾收集器清除,从而停止触发回调。

在类成员中保存对它的引用。

【讨论】:

    【解决方案3】:

    解决办法?

    就个人而言,我建议使用 RegisterWaitForSingleObject 函数而不是计时器,因为您遇到的确切原因。 RegisterWaitForSingleObject 注册一个委托,以便在您设置为类似于计时器的时间间隔调用,并且 超级 易于实现。您可以在几个小时内启动并运行测试工具。我在我的 Windows 服务中使用了这种间隔触发的方法,它是一个经过验证的真正稳定的解决方案,适合我。

    阅读下面的链接并转到文章中的链接以获取代码示例和演练。

    使用 Windows 服务在 .NET 中运行定期进程:
    http://allen-conway-dotnet.blogspot.com/2009/12/running-periodic-process-in-net-using.html

    【讨论】:

      【解决方案4】:

      以下是如何使用 RegisterWaitForSingleObject:

      当您有代码注册这样的计时器时:

      const int scheduledPeriodMilliseconds = 20000;
      new Timer(ServiceBusTimerCallback, parameters, 0, scheduledPeriodMilliseconds);
      
      private static void ServiceBusTimerCallback(object params)
      {
      }
      

      你可以有这个:

      const int scheduledPeriodMilliseconds = 20000;
      var allTasksWaitHandle = new AutoResetEvent(true);
      
      ThreadPool.RegisterWaitForSingleObject(
          allTasksWaitHandle,
          (s, b) => { ServiceBusTimerCallback(parameters); },
          null,
          scheduledPeriodMilliseconds,
          false);
      

      您可以在 ServiceBusTimerCallback 之后使用 allTask​​sWaitHandle.Set() 通知用户任务已完成,因此它将立即再次运行任务。上面发布的这段代码将在 timeont 过去后运行任务,因此每 20 秒运行一次。

      我在 WebAPI 项目中实现了它,效果很好。

      【讨论】:

        【解决方案5】:

        使用企业库记录和循环线程的 Windows 服务的完整示例。如果不使用企业库,请删除 logger.write 行

        namespace Example.Name.Space
        {
        public partial class SmsServices : ServiceBase
        {
            private static String _state = "";        
            private ManualResetEvent _stop = new ManualResetEvent(false);
            private static RegisteredWaitHandle _registeredWait;
            public WindowsServices()
            {
                InitializeComponent();
            }
        
            protected override void OnStart(string[] args)
            {                        
                Logger.Write("Starting service", LoggerCategory.Information);            
                _stop.Reset();
                _registeredWait = ThreadPool.RegisterWaitForSingleObject(_stop,
                    PeriodicProcess, null, 5000, false);
        
            }
        
            protected override void OnStop()
            {            
               // UpdateTimer.Stop();
                _stop.Set();
                Logger.Write("Stopping service", LoggerCategory.Information);
            }        
            private static void PeriodicProcess(object state, bool timedOut)
            {
        
                if (timedOut)
                {
                    // Periodic processing here
                    Logger.Write("Asserting thread state", LoggerCategory.Debug);
                    lock (_state)
                    {
                        if (_state.Equals("RUNNING"))
                        {
                            Logger.Write("Thread already running", LoggerCategory.Debug);
                            return;
                        }
                        Logger.Write("Starting thread", LoggerCategory.Debug);
                        _state = "RUNNING";
                    }
                    Logger.Write("Processing all messages", LoggerCategory.Information);
                    //Do something 
                    lock (_state)
                    {
                        Logger.Write("Stopping thread", LoggerCategory.Debug);
                        _state = "STOPPED";
                    }
                }
                else
                    // Stop any more events coming along
                    _registeredWait.Unregister(null);
        
        
            }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-06-10
          • 1970-01-01
          • 2011-08-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多