2010-02-15 31 views
1

我的Windows服務是一個具有大量緩存的數據服務器。在服務OnStop期間,我保存緩存以避免數據丟失。保存緩存可能需要幾分鐘,從而防止Windows服務管理器從超時我使用SetServiceStatus Win32的回調:在系統關閉期間.NET窗口服務中止

this.serviceStatus.currentState = (int)State.SERVICE_STOP_PENDING; 
this.serviceStatus.checkPoint = 1; 
this.serviceStatus.waitHint = 60000; 
SetServiceStatus(Process.GetCurrentProcess().Handle, ref this.serviceStatus); 

這工作正常。

我也將CanShutdown設置爲true,並添加了OnShutdown,以便服務將成爲系統關機證明。在這裏,我有效地做了OnStop中的同樣的事情:

protected override void OnShutdown() 
{ 
    this.OnStop(); 
    base.OnShutdown(); 
} 

這並不太好。當系統關閉時,當緩存被保存時,我得到「設備未準備就緒」。這表明Windows在停止/關閉之前會中止服務。用SetServiceStatus防止這種情況顯然不起作用。

如何獲得更多時間(延遲重啓)以完成保存?

任何建議表示歡迎。

+0

快速的問題 - waitHint爲60秒 - 1分鐘。這是你真正需要的嗎? (你說需要幾分鐘)。 – 2010-02-15 13:12:25

+2

我只需要成爲那個在這裏舉手的人,並提出了爲什麼你要實現一個長期存在的緩存行爲的問題。我並不是說你的整個設計是無效的,我只是說我聞到了一些東西。或者它可能是來自法國的非常好的奶酪,或者它可能是非常糟糕的。 – 2010-02-15 13:18:31

+0

我可以看到你的手舉起,戴夫。我知道你的想法 - 服務沒有把這些數據保存在內存中。但這是緩存的想法。無論如何緩存在幾種情況下都會被保存,但在系統關閉之前它可以被加載數據。而服務器應該很少重新啓動。但我需要做好最壞的準備。 – 2010-02-15 13:41:21

回答

0

經過一番測試,看起來這是系統的問題,而不是我的服務。

0

使用ManualResetEvent可能是個訣竅。

+0

我看不出ManualResetEvent在這裏有什麼好處。我無法控制線程請求服務關閉,我也不想同步它。我希望它可以防止Windows在OnShutdown結束之前終止我的服務。像SetServiceStatus這樣的OnStop。 – 2010-02-15 14:34:43

+0

由於ManualResetEvent基本上爲您提供了一種讓線程等待的方式,我認爲這會有所幫助。但是,我可以看到您的觀點 - 如果您無法檢測到另一個進程何時會關閉您的服務。像@ marc.d建議,但是,考慮更經常地保存這個緩存?他有一個非常有用的觀點。 – IAbstract 2010-02-15 17:10:06

+0

這是一個極端的系統。我更經常地保存緩存,但可能會有太多數據。它是一個寫入緩存。數據的速度可能比我能夠快速保存並且速度更快。訣竅是緩存重新安排數據(從水平到垂直),因此保存效率會更高效,因此我需要在保存之前累積一些數據。所以當系統關機發生時,我可能根本沒有數據或者有很多數據。 – 2010-02-15 18:45:34

2

處理此問題的首選方法可在this article on the BCL Team's blog中找到。本文包含了一些有關託管服務如何與SCM交互的背景知識,這對了解爲什麼不再推薦問題中顯示的方法很重要。

簡而言之,ServiceBase現在爲您和您的代碼處理服務狀態管理,只需要請求額外的時間。閱讀這篇文章,瞭解在.NET中編寫適用於SCM的服務的其他一些好的指導原則。

+0

有用,雖然不是精確的答案。我並沒有尋找從服務控制器請求更多時間的首選方式(但從現在開始將這樣做)。在博客的最後,我發現關於爲什麼關機與停止事件不同的信息。 – 2011-02-02 12:00:51

0

另一個簡單的方法,就如何包括setservicestatus方法搜索了幾個小時之後:

protected override void OnStop() 
    { 
     stopTimer(); 
     m_run = false; 
     while (m_queue.Count > 0) 
      Thread.Sleep(500); 
    } 
+0

正如我在我的問題中提到的,這將在停止期間工作,但不是在關閉期間工作,因爲如果服務在指定時間內沒有從OnStop返回,則會中止服務(由系統)。 – 2012-03-14 22:33:39