2011-04-15 45 views
3

我正在尋找一些關於實現Windows服務的一般建議。我的要求如下:實施Windows服務 - 我如何滿足這些要求?

  • 服務從數據庫處理行 - 所以,如果一排有一定地位的存在,它需要做一些工作,寫一些其他表,然後標記行作爲被處理。
  • 服務啓動時可能有成千上萬的等待處理的行 - 它應該處理它們全部。
  • 該服務應該繼續運行,處理任何行,因爲它們被寫入到我的ForProcessing表中。
  • 我需要能夠優雅地關閉它 - 我不希望任何一半處理的行
  • 它需要有效地執行 - 我不想成爲輪詢數據庫,如果可能的

所以我的具體問題是:

  • 如何保持活動狀態並在寫入新行時作出響應?我可以使用某種SQLDependency對象來有效地處理新行嗎?
  • 如何處理優雅的啓動和關閉?
  • 當從數據庫中提取行時,我應該提取所有正在等待處理的數據,還是一次只提取一行?
  • 假定它已經是後臺服務了,我會同步處理行嗎?換句話說,沒有必要在後臺線程上處理行?
  • 我需要從帳戶和運行權限的角度考慮一下什麼?這是部署問題嗎?
  • 任何其他陷阱或事情要注意?

感謝您的任何建議。

Ps。是否有任何其他合理的選擇使用Windows服務來實現這一點?

+0

這聽起來像你正在使用'ForProcessing'表作爲一種隊列形式。您是否閱讀過/考慮過Service Broker - 它是內置於SQL Server中的。它有一點自己的學習曲線(你可以把大部分邏輯放在一個CLR存儲過程中,所以你仍然主要編寫.NET代碼) – 2011-04-15 14:53:56

+0

如果你剛開始創建服務,這裏是一個在C#中一步一步:http://stackoverflow.com/questions/593454/easiest-language-for-creating-a-windows-service/593803#593803 – 2011-04-15 14:54:05

回答

5

編寫一個Windows服務並不是那麼困難,但最初看起來令人望而生畏。

至於沖洗出來的業務邏輯,我通常會先寫一個命令提示符程序,因爲它更容易調試整個很多。

現在,繼續服務。當然,使用Visual Studio創建Windows服務項目。

我該如何保持活躍狀態​​並在寫入新行時作出響應?我可以使用某種SQLDependency對象來有效地處理新行嗎?

嗯,我不知道你是否可以,但我可以告訴你你需要什麼。你將需要一個線程。如果您在OnStart事件中未創建新線程,則您的服務將立即停止。這個線程可以直接使用.NET的許多線程mechinisim創建,也可以通過某種類型的Timer,FileSystemWatcher(可能不適用於您)或其他可能的方法間接完成。

我該如何處理優雅啓動和關閉 ?

你在OnStop中這樣做。你可以通過發信號通知你的線程,或者通過一個全局變量,來關閉它。然後,由您的線程及時注意到信號並清理並退出線程。如果您處於可能需要20秒以上的時間內,則需要告訴SCM(服務控制管理器)您需要更多時間。如果你沒有停止服務的用戶得到消息說服務沒有響應,最終只會被殺死。

從db中拾取行時,我應該取所有正在等待處理的數據,還是一次只讀取一行?

這是一個商業決定。可能應該取決於每個處理需要多長時間,以便在發生停止時可以及時進行。

假設它已經是一個後臺服務,我會同步處理行嗎?換句話說,沒有必要在後臺線程上處理行?

同樣,這是一個商業決策,但是,我可能會保持同步。

我需要考慮一下賬戶和運行權限?這是部署問題嗎?

那麼,這一切都取決於。 SQL Server是否在同一個盒子上?您是否使用Windows身份驗證?如果SQL不在同一個框中,您將不得不使用用戶帳戶,或者使用Network Service。當您創建服務項目時,您需要添加一個安裝程序。當你的項目被創建時,你會得到一個組件類 - 在灰色屏幕上,右鍵單擊並選擇Add Installer。這將創建一個具有兩個已安裝模塊的新組件類。 serviceIntaller1具有諸如服務名稱,顯示名稱和描述以及啓動類型(手動,自動等)的內容。另一個是serviceProcessInstaller1,這是您決定使用哪個登錄帳戶的地方。

任何其他問題或意識到的東西?

呃,可能。但今天早上我還沒有喝咖啡。

真的,最重要的事情就是規劃如何讓線程保持活躍並響應最終的OnStop請求。例如,如果要嘗試使用SqlDependency類,則可能需要在OnStart中創建一個Manual或AutoResetEvent,啓動您的線程並讓您的線程設置爲SqlDependency,然後阻止重置事件。然後,在您的OnStop發佈您的重置事件,以便您的線程可以清理並離開。之後,這只是一個滑下山!

玩得開心!

+0

我會補充說,如果你正確地分離出你的業務邏輯從UI(這是一個控制檯應用程序或Windows服務),那麼從控制檯應用程序轉移到服務應該是相當簡單的。您可以在獨立的程序集中處理創建另一個線程,並在符號服務項目之外創建所有服務項目,這意味着您可以從控制檯或Windows服務啓動和停止服務,就像CruiseControl.Net一樣。 – Andy 2011-04-15 13:55:55

2

我的第一個問題是爲什麼觸發器或SQL工作不夠好?似乎兩者都足夠了。運行腳本以趕上處理,然後打開觸發器。

如果你是在一個服務上設置,那麼Jim有關於首先作爲控制檯程序運行的建議。或者做這樣的事情http://tech.einaregilsson.com/2007/08/15/run-windows-service-as-a-console-program/

另外http://topshelf-project.com/看起來也是一個非常好的起點。

您可能還想要處理該服務的暫停和重新啓動事件。再次像吉姆說,在另一個線程中產生你的處理。我只需要在我的服務中解決一個大問題,那就是我沒有這樣做,服務將處於初始狀態,您將無法輕鬆殺死它。 onStart方法必須返回。

相關問題