日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

.NET Worker Service 作为 Windows 服务运行及优雅退出改进

發(fā)布時(shí)間:2023/12/4 windows 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .NET Worker Service 作为 Windows 服务运行及优雅退出改进 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

上一篇文章我們了解了如何為 Worker Service 添加 Serilog 日志記錄,今天我接著介紹一下如何將 Worker Service 作為 Windows 服務(wù)運(yùn)行。

我曾經(jīng)在前面一篇文章的總結(jié)中提到過可以使用?sc.exe?實(shí)用工具將 Worker Service 安裝為 Windows 服務(wù)運(yùn)行,本文中我就來具體闡述一下如何實(shí)現(xiàn)它。

SC 是什么?

sc.exe?是包含于 Windows SDK 的,可用于控制服務(wù)的命令行實(shí)用程序,它的命令對應(yīng)于服務(wù)控制管理器(SCM)[1]?提供的函數(shù)。

服務(wù)控制管理器(SCM) 是 Windows NT 系列操作系統(tǒng)中的一個(gè)特殊進(jìn)程,它在操作系統(tǒng)啟動(dòng)時(shí)由 wininit 進(jìn)程啟動(dòng),用于啟動(dòng)和停止 Windows 進(jìn)程(包括設(shè)備驅(qū)動(dòng)程序和啟動(dòng)程序)。SCM 的主要功能是在系統(tǒng)啟動(dòng)時(shí)啟動(dòng)所有必需的服務(wù),它類似于類 Unix 系統(tǒng)上的 init 進(jìn)程(或者現(xiàn)代 Linux 發(fā)行版上使用的較新的 systemd init 系統(tǒng)),用于啟動(dòng)各種系統(tǒng)守護(hù)進(jìn)程[2]。SCM 是一個(gè)遠(yuǎn)程過程調(diào)用(RPC)服務(wù),服務(wù)配置和服務(wù)控制程序可以借它來控制遠(yuǎn)程計(jì)算機(jī)上的服務(wù)。

打開 Windows 命令提示符窗口,輸入并運(yùn)行?sc?命令,您便可以看到?sc.exe?實(shí)用工具的幫助信息:

> sc描述:SC 是用來與服務(wù)控制管理器和服務(wù)進(jìn)行通信的命令行程序。 用法:sc <server> [command] [service name] <option1> <option2>...<server> 選項(xiàng)的格式為 "\\ServerName"可通過鍵入以下命令獲取有關(guān)命令的更多幫助: "sc [command]"命令:query-----------查詢服務(wù)的狀態(tài),或枚舉服務(wù)類型的狀態(tài)。queryex---------查詢服務(wù)的擴(kuò)展?fàn)顟B(tài),或枚舉服務(wù)類型的狀態(tài)。start-----------啟動(dòng)服務(wù)。pause-----------向服務(wù)發(fā)送 PAUSE 控制請求。interrogate-----向服務(wù)發(fā)送 INTERROGATE 控制請求。continue--------向服務(wù)發(fā)送 CONTINUE 控制請求。stop------------向服務(wù)發(fā)送 STOP 請求。config----------更改服務(wù)的配置(永久)。description-----更改服務(wù)的描述。failure---------更改失敗時(shí)服務(wù)執(zhí)行的操作。failureflag-----更改服務(wù)的失敗操作標(biāo)志。sidtype---------更改服務(wù)的服務(wù) SID 類型。privs-----------更改服務(wù)的所需特權(quán)。managedaccount--更改服務(wù)以將服務(wù)帳戶密碼標(biāo)記為由 LSA 管理。qc--------------查詢服務(wù)的配置信息。qdescription----查詢服務(wù)的描述。qfailure--------查詢失敗時(shí)服務(wù)執(zhí)行的操作。qfailureflag----查詢服務(wù)的失敗操作標(biāo)志。qsidtype--------查詢服務(wù)的服務(wù) SID 類型。qprivs----------查詢服務(wù)的所需特權(quán)。qtriggerinfo----查詢服務(wù)的觸發(fā)器參數(shù)。qpreferrednode--查詢服務(wù)的首選 NUMA 節(jié)點(diǎn)。qmanagedaccount-查詢服務(wù)是否將帳戶與 LSA 管理的密碼結(jié)合使用。qprotection-----查詢服務(wù)的進(jìn)程保護(hù)級別。quserservice----查詢用戶服務(wù)模板的本地實(shí)例。delete ----------(從注冊表中)刪除服務(wù)。create----------創(chuàng)建服務(wù)(并將其添加到注冊表中)。control---------向服務(wù)發(fā)送控制。sdshow----------顯示服務(wù)的安全描述符。sdset-----------設(shè)置服務(wù)的安全描述符。showsid---------顯示與任意名稱對應(yīng)的服務(wù) SID 字符串。triggerinfo-----配置服務(wù)的觸發(fā)器參數(shù)。preferrednode---設(shè)置服務(wù)的首選 NUMA 節(jié)點(diǎn)。GetDisplayName--獲取服務(wù)的 DisplayName。GetKeyName------獲取服務(wù)的 ServiceKeyName。EnumDepend------枚舉服務(wù)依賴關(guān)系。 ...

您可以從幫助信息中看到?sc?實(shí)用工具支持的所有命令集及其介紹。我們在本文中要用到的命令有:

  • create----------創(chuàng)建服務(wù)(并將其添加到注冊表中)

  • description-----更改服務(wù)的描述。

  • start-----------啟動(dòng)服務(wù)。

  • stop------------向服務(wù)發(fā)送 STOP 請求。

  • delete ----------(從注冊表中)刪除服務(wù)。

創(chuàng)建項(xiàng)目并發(fā)布

§下載 Worker Service 源碼

我將基于上一篇文章中的 Worker Service 源碼[3]來修改,如果您安裝有 git,可以用下面的命令獲取它:

git clone git@github.com:ITTranslate/WorkerServiceWithSerilog.git

然后,使用 Visual Studio Code 打開此項(xiàng)目,運(yùn)行一下,以確保一切正常:

dotnet build dotnet run

§添加 Windows Services 依賴

為了作為 Windows 服務(wù)運(yùn)行,我們需要我們的 Worker 監(jiān)聽來自?ServiceBase?的啟動(dòng)和停止信號,ServiceBase?是將 Windows 服務(wù)系統(tǒng)公開給 .NET 應(yīng)用程序的 .NET 類型。為此,我們需要添加?Microsoft.Extensions.Hosting.WindowsServices?NuGet 包:

dotnet add package Microsoft.Extensions.Hosting.WindowsServices

然后修改?Program.cs?中的?CreateHostBuilder?方法,添加?UseWindowsService?方法調(diào)用:

public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).UseWindowsService() // Sets the host lifetime to WindowsServiceLifetime....ConfigureServices((hostContext, services) =>{services.AddHostedService<Worker>();}).UseSerilog(); //將 Serilog 設(shè)置為日志提供程序

然后,運(yùn)行一下構(gòu)建命令,確保一切正常:

dotnet build

不出意外,您會(huì)看到?已成功生成?的提示。

§發(fā)布程序

運(yùn)行?dotnet publish?命令將應(yīng)用程序及其依賴項(xiàng)發(fā)布到文件夾(我的操作系統(tǒng)是 win10 x64 系統(tǒng))[4]。

dotnet publish -c Release -r win-x64 -o c:\test\workerpub

命令運(yùn)行完成后,您會(huì)在?C:\test\workerpub?文件夾中看到可執(zhí)行程序及其所有依賴項(xiàng)。

創(chuàng)建并運(yùn)行服務(wù)

首先,需要特別注意的是:當(dāng)我們使用?sc.exe?實(shí)用工具管理服務(wù)時(shí),必須以管理員身份運(yùn)行 Windows 命令提示符,否則會(huì)執(zhí)行失敗。

§安裝服務(wù)

安裝服務(wù)我們需要用到創(chuàng)建服務(wù)命令 ——?sc create。

以管理員身份打開 Windows 命令提示符窗口,輸入并運(yùn)行?sc create?命令,可以看到此命令的的幫助信息:

> sc create描述:在注冊表和服務(wù)數(shù)據(jù)庫中創(chuàng)建服務(wù)項(xiàng)。 用法:sc <server> create [service name] [binPath= ] <option1> <option2>...選項(xiàng): 注意: 選項(xiàng)名稱包括等號。等號和值之間需要一個(gè)空格。type= <own|share|interact|kernel|filesys|rec|userown|usershare>(默認(rèn) = own)start= <boot|system|auto|demand|disabled|delayed-auto>(默認(rèn) = demand)error= <normal|severe|critical|ignore>(默認(rèn) = normal)binPath= <.exe 文件的 BinaryPathName>group= <LoadOrderGroup>tag= <yes|no>depend= <依存關(guān)系(以 / (斜杠)分隔)>obj= <AccountName|ObjectName>(默認(rèn)= LocalSystem)DisplayName= <顯示名稱>password= <密碼>

命令?sc create?的參數(shù)說明[5]

  • server:指定服務(wù)所在的遠(yuǎn)程服務(wù)器的名稱。名稱必須使用通用命名約定(UNC)格式 (例如,\myserver) 。若要在本地運(yùn)行 SC.exe,請不要使用此參數(shù)。

  • service name:指定?getkeyname?操作返回的服務(wù)名稱。

  • binPath=:指定服務(wù)二進(jìn)制文件的路徑。binPath= 沒有默認(rèn)值,必須提供此字符串。

  • displayname= "顯示名稱":指定一個(gè)友好名稱,用于標(biāo)識用戶界面程序中的服務(wù)。

  • start= {boot|system|auto|demand|disabled|delayed-auto}:指定服務(wù)的啟動(dòng)類型。選項(xiàng)包括:

    • boot - 指定由啟動(dòng)加載程序加載的設(shè)備驅(qū)動(dòng)程序。

    • system - 指定在內(nèi)核初始化過程中啟動(dòng)的設(shè)備驅(qū)動(dòng)程序。

    • auto - 指定一項(xiàng)服務(wù),該服務(wù)在計(jì)算機(jī)每次重新啟動(dòng)時(shí)自動(dòng)啟動(dòng)并運(yùn)行(即使沒有人登錄到計(jì)算機(jī))。

    • demand - 指定必須手動(dòng)啟動(dòng)的服務(wù)。如果未指定 start= ,則此值為默認(rèn)值。

    • disabled - 指定無法啟動(dòng)的服務(wù)。若要啟動(dòng)已禁用的服務(wù),請將啟動(dòng)類型更改為其他某個(gè)值。

    • delayed-auto - 指定一項(xiàng)服務(wù),該服務(wù)將在啟動(dòng)其他自動(dòng)服務(wù)之后的短時(shí)間自動(dòng)啟動(dòng)。

注意事項(xiàng):
1、每個(gè)命令行選項(xiàng) (參數(shù)) 必須包含等號作為選項(xiàng)名稱的一部分。
2、選項(xiàng)與其值之間必須有一個(gè)空格(例如,type= own),如果遺漏了空格,操作將失敗。

了解了?sc create?命令的用法,不難得出此處我們所需要的命令如下:

sc create MyService binPath= "C:\test\workerpub\MyService.exe" start= auto displayname= "技術(shù)譯站的測試服務(wù)"

運(yùn)行以上命令,輸出以下結(jié)果:

[SC] CreateService 成功

運(yùn)行?services.msc?命令打開本地服務(wù)列表,可以看到我們的服務(wù)已經(jīng)安裝好了,服務(wù)名稱顯示為?技術(shù)譯站的測試服務(wù)。它沒有描述,處于已停止?fàn)顟B(tài)。

§設(shè)置服務(wù)的描述

輸入并運(yùn)行?sc description?命令,可以看到此命令的的幫助信息:

> sc description 描述:設(shè)置服務(wù)的描述字符串。 用法:sc <server> description [service name] [description]

運(yùn)行以下命令給該服務(wù)添加描述信息:

sc description MyService "這是一個(gè)由 Worker Service 實(shí)現(xiàn)的測試服務(wù)。"

輸出結(jié)果:

[SC] ChangeServiceConfig2 成功

運(yùn)行成功以后,按?F5?刷新服務(wù)列表,您將看到服務(wù)描述已經(jīng)更新了。

§啟動(dòng)服務(wù)

輸入并運(yùn)行?sc start?命令,可以看到此命令的的幫助信息:

> sc start描述:啟動(dòng)服務(wù)運(yùn)行。 用法:sc <server> start [service name] <arg1> <arg2> ...

輸入以下命令啟動(dòng)服務(wù):

sc start MyService

輸出結(jié)果:

[SC] StartService 失敗 1053:服務(wù)沒有及時(shí)響應(yīng)啟動(dòng)或控制請求。

啟動(dòng)失敗了,為什么呢?查看一下 Windows 事件查看器 --> 應(yīng)用程序,顯示的錯(cuò)誤原因大致如下:

The process was terminated due to an unhandled exception. Exception Info: System.IO.FileNotFoundException: The configuration file 'appsettings.json' was not found and is not optional. The physical path is 'C:\WINDOWS\system32\appsettings.json'.

回頭看一下?Program.cs?文件,在?Main?方法中我們?yōu)榕渲迷O(shè)置的基路徑是?Directory.GetCurrentDirectory()。但是作為 Windows Service 運(yùn)行時(shí),默認(rèn)的當(dāng)前工作目錄是?C:\WINDOWS\system32,所以導(dǎo)致了這樣的錯(cuò)誤。為了解決這一問題,我們需要在設(shè)置配置的基路徑前添加一行?Directory.SetCurrentDirectory(AppContext.BaseDirectory),代碼如下:

// 作為 Windows Service 運(yùn)行時(shí),默認(rèn)的當(dāng)前工作目錄是 C:\WINDOWS\system32,會(huì)導(dǎo)致找不到配置文件, // 所以需要添加下面一行,指定當(dāng)前工作目錄為應(yīng)用程序所在的實(shí)際目錄。 Directory.SetCurrentDirectory(AppContext.BaseDirectory);var configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json").AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? "Production"}.json", true).Build();

作為 Windows Service 運(yùn)行時(shí),默認(rèn)情況下,Directory.GetCurrentDirectory() 為?C:\WINDOWS\system32,
AppDomain.CurrentDomain.BaseDirectory 和 AppContext.BaseDirectory 為應(yīng)用程序所在的實(shí)際目錄。
因?yàn)樵谟械囊蕾嚦绦虬杏杏玫?Directory.GetCurrentDirectory() 獲取來程序所在目錄,所以這里必須使用 Directory.SetCurrentDirectory 設(shè)置當(dāng)前工作目錄。

再次啟動(dòng)服務(wù):

> sc start MyServiceSERVICE_NAME: MyServiceTYPE : 10 WIN32_OWN_PROCESSSTATE : 2 START_PENDING(NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)WIN32_EXIT_CODE : 0 (0x0)SERVICE_EXIT_CODE : 0 (0x0)CHECKPOINT : 0x0WAIT_HINT : 0x7d0PID : 21736FLAGS :

這次服務(wù)啟動(dòng)成功了。

§停止服務(wù)

運(yùn)行以下命令,停止?MyService?服務(wù)。

sc stop MyService

輸出結(jié)果:

SERVICE_NAME: MyServiceTYPE : 10 WIN32_OWN_PROCESSSTATE : 3 STOP_PENDING(STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN)WIN32_EXIT_CODE : 0 (0x0)SERVICE_EXIT_CODE : 0 (0x0)CHECKPOINT : 0x0WAIT_HINT : 0x0

§刪除服務(wù)

運(yùn)行以下命令,(從注冊表中)刪除?MyService?服務(wù)。

sc delete MyService

輸出結(jié)果:

[SC] DeleteService 成功

至此,我們使用?sc?實(shí)用工具演示了服務(wù)的創(chuàng)建、更改描述、啟動(dòng)、停止和刪除。當(dāng)服務(wù)創(chuàng)建完成以后,您也可以使用 Windows 服務(wù)管理器來維護(hù)服務(wù)的啟動(dòng)、停止等。

Windows Service 優(yōu)雅退出

§問題

我查看了一下?C:\test\workerpub\Logs?目錄下的日志信息,發(fā)現(xiàn)當(dāng)停止服務(wù)的時(shí)候,它并沒有像我將 Worker Service 作為控制臺應(yīng)用運(yùn)行時(shí)那樣優(yōu)雅退出(等待關(guān)閉前必須完成的任務(wù)正常結(jié)束后再退出)。也就是說,我在.NET Worker Service 如何優(yōu)雅退出[6]中使用的方法,在將 Worker Service 作為 Windows 服務(wù)運(yùn)行時(shí)失效了。

這是什么原因呢,該如何解決呢?

§查找原因

我們來看一下?UseWindowsService?方法的源代碼:

其中有這樣一行:

// https://github.com/dotnet/runtime/blob/main/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/WindowsServiceLifetimeHostBuilderExtensions.csservices.AddSingleton<IHostLifetime, WindowsServiceLifetime>();

也就是說,當(dāng) Worker Service 作為 Windows Service 運(yùn)行時(shí),使用的宿主(Host)生命周期控制類不再是作為控制臺應(yīng)用運(yùn)行時(shí)的?ConsoleLifetime,而是?WindowsServiceLifetime,它派生自?ServiceBase。

讓我們來看一下?WindowsServiceLifetime?的源代碼:

您會(huì)發(fā)現(xiàn)?WindowsServiceLifetime?類的?OnStop?和?OnShutdown?方法中調(diào)用了?ApplicationLifetime.StopApplication();而它的基類?ServiceBase?中,當(dāng)服務(wù)停止時(shí)調(diào)用了?OnStop?和?OnShutdown?方法。也就是說,在 Windows 服務(wù)停止的時(shí)候已經(jīng)調(diào)用了?ApplicationLifetime.StopApplication()。這就是我們在?Worker?中手動(dòng)調(diào)用?StopApplication?失效的原因。

問題的原因找到了,該怎么解決它呢?

§解決方法

功夫不負(fù)有心人,在認(rèn)真查閱了?dotnet runtime[7]?中?BackgroundService?、WindowsServiceLifetime?和?ApplicationLifetime?類的源代碼后,終于找到了解決方法。既然?WindowsServiceLifetime?中調(diào)用了?StopApplication,那我就換別的方法唄。

注意到?ApplicationLifetime?的屬性?ApplicationStopping(類型為?CancellationToken),它的注釋是:

Triggered when the application host is performing a graceful shutdown. Request may still be in flight. Shutdown will block until this event completes.

所以,我們可以向它注冊一個(gè)取消時(shí)調(diào)用的的委托操作。修改一下?Worker?類中的?StartAsync?方法,添加以下代碼:

// 注冊應(yīng)用停止前需要完成的操作 _hostApplicationLifetime.ApplicationStopping.Register(() => {GetOffWork(); });

向 ApplicationStopping 注冊的委托,在?StopAsync?之前運(yùn)行。

修改后?Worker?類的完整代碼如下:

public class Worker : BackgroundService {/// <summary>/// 狀態(tài):0-默認(rèn)狀態(tài),1-正在完成關(guān)閉前的必要工作,2-正在執(zhí)行 StopAsync/// </summary>private volatile int _status = 0; //狀態(tài)private readonly IHostApplicationLifetime _hostApplicationLifetime;private readonly ILogger<Worker> _logger;public Worker(IHostApplicationLifetime hostApplicationLifetime, ILogger<Worker> logger){_hostApplicationLifetime = hostApplicationLifetime;_logger = logger;}public override Task StartAsync(CancellationToken cancellationToken){// 注冊應(yīng)用停止前需要完成的操作_hostApplicationLifetime.ApplicationStopping.Register(() =>{GetOffWork();});_logger.LogInformation("上班了,又是精神抖擻的一天,output from StartAsync");return base.StartAsync(cancellationToken);}protected override async Task ExecuteAsync(CancellationToken stoppingToken){try{// 這里實(shí)現(xiàn)實(shí)際的業(yè)務(wù)邏輯while (!stoppingToken.IsCancellationRequested){try{_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);await SomeMethodThatDoesTheWork(stoppingToken);}catch (Exception ex){_logger.LogError(ex, "Global exception occurred. Will resume in a moment.");}await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);}}finally{_logger.LogWarning("My worker service shut down.");}}private async Task SomeMethodThatDoesTheWork(CancellationToken cancellationToken){string msg = _status switch{1 => "正在完成關(guān)閉前的必要工作……",2 => "假裝還在埋頭苦干ing…… 其實(shí)我去洗杯子了",_ => "我愛工作,埋頭苦干ing……"};_logger.LogInformation(msg);await Task.CompletedTask;}/// <summary>/// 關(guān)閉前需要完成的工作/// </summary>private void GetOffWork(){_status = 1;_logger.LogInformation("太好了,下班時(shí)間到,output from ApplicationStopping.Register Action at: {time}", DateTimeOffset.Now); _logger.LogDebug("開始處理關(guān)閉前必須完成的工作 at: {time}", DateTimeOffset.Now);_logger.LogInformation("糟糕,有一個(gè)緊急 bug 需要下班前完成!!!");_logger.LogInformation("啊啊啊,我愛加班,我要再干 20 秒,Wait 1 ");Task.Delay(TimeSpan.FromSeconds(20)).Wait();_logger.LogInformation("啊啊啊啊啊啊,我愛加班,我要再干 1 分鐘,Wait 2 ");Task.Delay(TimeSpan.FromMinutes(1)).Wait();_logger.LogInformation("啊哈哈哈哈哈,終于好了,可以下班了!");_logger.LogDebug("關(guān)閉前必須完成的工作處理完成 at: {time}", DateTimeOffset.Now);}public override Task StopAsync(CancellationToken cancellationToken){_status = 2;_logger.LogInformation("準(zhǔn)備下班了,output from StopAsync at: {time}", DateTimeOffset.Now);_logger.LogInformation("去洗洗茶杯先……", DateTimeOffset.Now);Task.Delay(30_000).Wait();_logger.LogInformation("茶杯洗好了。", DateTimeOffset.Now);_logger.LogInformation("下班嘍 ^_^", DateTimeOffset.Now);return base.StopAsync(cancellationToken);} }

代碼修改完成以后,停止服務(wù),重新發(fā)布程序。

dotnet publish -c Release -r win-x64 -o c:\test\workerpub

再次啟動(dòng)服務(wù)然后關(guān)閉服務(wù),您會(huì)發(fā)現(xiàn),我們編寫的 Windows Service 已經(jīng)可以優(yōu)雅退出了。

這種方法,不僅作為 Windows 服務(wù)運(yùn)行時(shí)可以優(yōu)雅退出,而且作為控制臺應(yīng)用運(yùn)行時(shí)也一樣適用,它比我在.NET Worker Service 如何優(yōu)雅退出中介紹的方法更加完美。

總結(jié)

在本文中,我通過一個(gè)實(shí)例詳細(xì)介紹了如何將 .NET Worker Service 作為 Windows 服務(wù)運(yùn)行,并說明了如何使用?sc.exe?實(shí)用工具安裝和管理服務(wù)。還改進(jìn)了 Worker Service 優(yōu)雅退出的方法,使它不僅適用于控制臺應(yīng)用而且適用于 Windows 服務(wù)。

當(dāng)我們向?HostBuilder?添加了?.UseWindowsService()?方法調(diào)用后,編譯出的程序,既可以作為控制臺應(yīng)用運(yùn)行,也可以作為 Windows 服務(wù)運(yùn)行。

您可以從 GitHub?下載本文中的源碼[8]。

相關(guān)閱讀:

  • .NET Worker Service 入門介紹

  • .NET Worker Service 如何優(yōu)雅退出

  • .NET Worker Service 添加 Serilog 日志記錄


相關(guān)鏈接:

  • https://docs.microsoft.com/zh-cn/windows/win32/services/service-control-manager???

  • https://www.techopedia.com/definition/25522/service-control-manager-scm???

  • https://github.com/ITTranslate/WorkerServiceWithSerilog???

  • https://docs.microsoft.com/zh-cn/dotnet/core/tools/dotnet-publish???

  • https://docs.microsoft.com/zh-cn/windows-server/administration/windows-commands/sc-create???

  • https://mp.weixin.qq.com/s/voxAxh9rQQogE3_Yc1-eCQ???

  • https://github.com/dotnet/runtime?dotnet runtime???

  • https://github.com/ITTranslate/WorkerServiceAsWindowsService?源碼下載???

  • 作者 :技術(shù)譯民
    出品 :技術(shù)譯站(https://ITTranslator.cn/)

    END

    創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

    總結(jié)

    以上是生活随笔為你收集整理的.NET Worker Service 作为 Windows 服务运行及优雅退出改进的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。