2011-10-20 94 views
0

部署我的Windows服務的WIN2K3 Server時,我目前有一個System.Threading.Timer的麻煩上。它的工作原理就好滴答每秒(矯枉過正用於調試)我的本地機器上,當我安裝它,但我把它安裝到服務器後,該服務成功啓動之後再也沒有觸發一次計時器事件。有沒有人遇到類似這種情況?我的大部分研究都發現了.NET 1.1中永遠存在的問題。感謝您的時間和幫助。System.Threading.Timer不滴答作響的Windows Server 2003

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 
     } 
    } 

UPDATE:

我發現它是與該服務需要爲運行的用戶。當服務作爲系統運行時,線程工作得很好。任何人都知道用戶需要什麼權限才能運行這些線程?我已經嘗試在本地安全設置中使用「作爲操作系統的一部分」,但這只是導致服務啓動,然後在以我添加的用戶身份登錄時立即失敗。

+0

真的很明顯的問題:什麼是服務器上'SleepTime'在app.config價值?其他選項:改用'System.Timers.Timer'。 – ligos

+0

在我以這種方式實現它之前,我有一個System.Timers.Timer。我在我的服務器上得到了同樣的行爲,服務將啓動,然後定時器事件永遠不會觸發。然後我讀到Win 2k3服務器做了一些有趣的線程工作,而Timer可能無法工作。我的測試目的,SleepTime值現在爲1秒。稍後它會是我不需要測試時所需要的。 – mtgibbs21

+0

你能發佈有關w2k3行爲的鏈接嗎?你可以建立一個控制檯測試應用程序,以排除贏得服務的東西?用'Console.WriteLine'測試也會容易得多。而且,對不起要問愚蠢的問題,「SleepTime」是1000毫秒= 1秒,對吧? – ligos

回答

0

一對夫婦的解決方案我可以建議:

  1. 使用一個控制檯應用程序,而不是一個窗口服務。從任務計劃程序運行您的控制檯應用程序。
  2. 建立自己的定時器類。使用您自己的線程並在您的輪詢間隔中休息。喚醒後,做你的工作。然後再睡一會兒。

以及物品是否完整,這裏有一些細節該文章的真正的Bug:

+0

這是一個很好的信息彙編。我打算將此標記爲解決方案,以便人們知道要閱讀這些解決方案。 – mtgibbs21

1

定時器可能被解僱。您可以在目標機器上運行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"); 
+0

我有事件消息,當它發生時,但我什麼也沒有。定時器內部的工作也沒有完成。我已經在沒有計時器的情況下安裝了它,只是運行doWork()部分,它的行爲和我所期望的一樣,甚至寫出它應該在事件日誌中的位置。所以這與定時器和線程完全相關。 – mtgibbs21

+1

我不知道如果用戶服務正在運行下沒有訪問:ConfigurationManager.AppSettings [「SleepTime」]?它沒有任何意義,但是你可以硬編碼一個值而不是讀它,看看是否有幫助。 –

+0

@ mtgibbs21:我也建議確保'OnStart'方法實際上按照您的期望啓動計時器。你應該在調用OnStart時輸出消息的代碼,interval的值以及OnStart退出。它看起來像計時器沒有被創建。 –

0

好吧。感謝您對此的所有建議。我做了一個非常積極的日誌方案,我相信服務器由於某種原因正在殺死我的線程。我添加了一個GC.KeepAlive(workTimer),它似乎已經解決了計時器不勾選的問題。

以防萬一別人運行到這個問題,在我看來,在本地系統得到線程的優先級,而其他用戶將有可能已經銷燬由於某種原因或其他的線程。由於我沒有完全訪問我正在部署的服務器,因此我會將修補程序添加到KeepAlive或服務器團隊中,以固定我的背後。

+0

很高興你找到了一些方法來使它工作。我已經發布了一些其他可能的解決方案,可能會或可能不會對您有所幫助(但可能對其他人)。還有一些詳細說明錯誤的文章。 – ligos