Windows Server 2003上的System.Threading.Timer不滴答

本文关键字:Timer 滴答 Threading System Server 2003 上的 Windows | 更新日期: 2023-09-27 18:11:40

我目前在部署Windows服务到Win2k3服务器时遇到了System.Threading.Timer的问题。当我安装它时,它在我的本地机器上每秒滴答滴答地工作得很好(对于调试目的来说,这是多余的),但是在我将它安装到服务器上之后,服务成功启动,然后从未触发计时器事件一次。以前有人遇到过类似的情况吗?我的大部分研究都发现了。net 1.1中从很久以前就普遍存在的问题。谢谢你的时间和帮助。

   protected override void OnStart(string[] args)
   {
        int interval = Int32.Parse(ConfigurationManager.AppSettings["SleepTime"]) * 1000;
        TimerCallback cb = new TimerCallback(ProcessTimerEvent);
        QueueWorker worker = new QueueWorker();
        workTimer = new Timer(cb, worker, interval, 1000);
    }
    private static void ProcessTimerEvent(object obj)
    {
        if (obj is QueueWorker)
        {
            QueueWorker qw = (QueueWorker)obj;
            qw.doWork();
        }
    }
    class QueueWorker
    {
        public void doWork()
        {
           // work happening here
        }
    }

更新:

我发现它与服务需要以何种用户身份运行有关。当服务作为System运行时,线程工作得很好。有人知道用户需要什么权限才能运行线程吗?我试过在本地安全设置中使用"作为操作系统的一部分",但这只会导致服务启动,然后在以我添加的用户登录时立即失败。

Windows Server 2003上的System.Threading.Timer不滴答

计时器可能正在触发。你可以在目标机器上运行DebugView:

http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx

然后你可以在你的代码中加入调用,看看是什么在执行,像这样:

System.Diagnostics.Debug.WriteLine("Beginning of Timer event...");
System.Diagnostics.Debug.WriteLine("End of Timer event");

我可以提出几个解决方案:

  1. 使用控制台应用程序而不是windows服务。从任务调度程序中运行控制台应用程序。建立你自己的定时器类。使用您自己的线程并在轮询间隔内休眠。醒来后,做你的工作。然后再睡。

为了完整起见,这里有一些详细描述实际bug的文章:

  • http://support.microsoft.com/?kbid=900822
  • http://objectmix.com/dotnet/97213-serious-regression-win2k3-sp1-kills-timers.html
  • http://groups.google.com/group/microsoft.public.dotnet.framework.performance/browse_thread/thread/8f4430b6f6efe829/5224d5666844a215?hl=en
  • http://groups.google.com/group/microsoft.public.dotnet.framework.clr/browse_thread/thread/72a5528aba714fa/eeee6f6d9601c90b?hl=en
  • http://www.windowskb.com/Uwe/Forum.aspx/virtual-pc/5593/System-Threading-Timers-Not-Firing

好的。谢谢你的建议。我做了一个非常激进的日志方案,我相信服务器出于某种原因杀死了我的线程。我添加了一个GC.KeepAlive(workTimer),它似乎已经解决了定时器不滴答的问题。

只是以防其他人遇到这个问题,在我看来,本地系统获得线程优先级,但其他用户可能会因为某种原因或其他原因而销毁他们的线程。由于我没有完全访问服务器,我正在部署这个,我将把修复归咎于KeepAlive或服务器团队在我背后修复了一些东西。