2019第一篇文章。
此文源於前公司在遷移專案到.NET Core的過程中,希望使用Generic Host來管理定時任務程式時,沒法部署到Windows服務的問題,而且官方也沒給出解決方案,只能關註一下官方issue #809 等他們方解決了。
官方檔案只提供了一個《在 Windows 服務中託管 ASP.NET Core》的方案,可以使用Microsoft.AspNetCore.Hosting.WindowsServices
類庫來把Web應用部署為Windows服務。但是ASP.NET Core雖然是控制檯程式,但是它本身是使用了含有HTTP管道的Web Host來負責應用程式的生命週期管理,用它來作為定時任務的話,會有很多不必要的工作負載,例如佔用埠、增加了很多依賴等等。
官方意識到這個問題之後,在.NET Core 2.1版本新增了Generic Host通用主機,剝離了原來WebHost的Http管道相關的API,原始碼中可以發現Web Host已經基於Generic Host實現。它才是作為純粹定時任務程式的最佳拍檔。
但是由於Generic Host本身非常簡單,用它執行的程式設定在註冊為Windows服務啟動之後會自動停止。研究很久之後才知道,想在Windows上啟動服務,還是不能像Linux上那麼簡單——
於是嘗試結合Topshelf來建立Windows服務,最終成功了。
1|1實現方法
- 先實現
IHostLifetime
介面來接管應用程式的生命週期,其實就是用空的實現來替換掉預設的ConsoleLifetime,這樣就可以在之後由Topshelf框架內部去管理生命週期。 - 然後實現
IHostedService
介面,把後臺任務邏輯寫到StartAsync
方法中,參見官方檔案《在 ASP.NET Core 中使用託管服務實現後臺任務》,本文示例使用定時寫入文字到一個檔案來測試定時任務是否成功執行。 - 構建Generic Host,在
ConfigureServices
方法中註冊TopshelfLifetime
,並且註冊一個託管服務FileWriterService
,就能完成Generic Host的簡單構建,當然完整的專案應該還包含配置、日誌等等。最後,使用Topshelf來接管Generic Host,建立Windows服務。 - 最後釋出應用程式,並安裝到Windows服務。
以管理員許可權開啟終端,執行命令:
這樣這個Windows服務就啟動了!檢視輸出檔案,可以看到定時寫入成功,服務也一直沒關閉~
1|2示例程式碼https://github.com/ElderJames/GenericHostWindowsServiceWithTopshelf
1|3參考連結
官方檔案《.NET 通用主機》
官方檔案《在 ASP.NET Core 中使用託管服務實現後臺任務》
原文地址:https://www.cnblogs.com/ElderJames/p/Using-Topshelf-To-Deploy-Net-Core-Generic-Host-App-To-Windows-Services.html