当前位置:网站首页>. How to exit net worker service gracefully
. How to exit net worker service gracefully
2022-06-25 18:15:00 【Phil Arist】
Worker class
from Last article in , We already know that Worker Service Templates provide us with three core files out of the box , among Worker Class is inherited from the abstract base class BackgroundService Of , and BackgroundService Realized IHostedService Interface . Final Worker Class will be registered as a managed service , The core code of our task is written in Worker Class . therefore , We need to focus on Worker And its base class .
Let's look at its base class first BackgroundService :

Base class BackgroundService There are three overridable methods in , Let's bind to the life cycle of the application :
Abstract method
ExecuteAsync: Methods as the main entry point to the application . If this method exits , The application will close . We have to Worker To achieve it .Virtual method
StartAsync: Call... When the application starts . if necessary , You can override this method , It can be used to set up resources once when the service starts ; Of course , It can also be ignored .Virtual method
StopAsync: Call... When the application closes . if necessary , You can override this method , Release resources and destroy objects on shutdown ; Of course , It can also be ignored .
By default Worker Just rewrite the necessary abstract methods ExecuteAsync.
Create a new one Worker Service project
Let's build a new one Worker Service, Use Task.Delay To simulate some operations that must be completed before closing , See if it can be done simply by ExecuteAsync in Delay To simulate graceful closing .
Development tools needed :
Visual Studio Code:https://code.visualstudio.com/
Abreast of the times .NET SDK:https://dotnet.microsoft.com/download
After installing the above tools , Run the following command in the terminal , Create a Worker Service project :
dotnet new Worker -n "MyService"
Create good Worker Service after , stay Visual Studio Code Open the application in , Then build and run , To make sure everything is OK :
dotnet build
dotnet run
Press CTRL+C Key to turn off the service , The service will exit immediately , By default Worker Service That's how direct it is to shut down ! In many scenarios ( Like queues in memory ) in , This is not the result we want , Sometimes we have to complete some necessary resource recycling or transaction processing before the service is shut down .
Let's see Worker Class code , You'll see that it just rewrites the base class BackgroundService Abstract methods in ExecuteAsync:
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
}
}
Let's try to modify this method , Do some business processing before quitting :
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
// await Task.Delay(1000, stoppingToken);
await Task.Delay(1000);
}
_logger.LogInformation(" Waiting to exit {time}", DateTimeOffset.Now);
Task.Delay(60_000).Wait(); // What needs to be done before the simulation exits
_logger.LogInformation(" sign out {time}", DateTimeOffset.Now);
}
And test it out , See if it will wait as we expected 60 Turn it off in seconds .
dotnet build
dotnet run
Press CTRL+C Key to turn off the service , We will find that , It's outputting “ Waiting to exit ” after , There is no waiting 60 Seconds and output “ sign out ” And then close , It was quitting soon . It's like a familiar console application , By default , We click the close button in the upper right corner or press CTRL+C Key time , It's just like shutting it down .
Worker Service Graceful exit
that , How to achieve elegant exit ?
The method is actually very simple , That's going to be IHostApplicationLifetime Into our services , Then call... Manually when the application stops IHostApplicationLifetime Of StopApplication Method to close the application .
modify Worker Constructor for , Inject IHostApplicationLifetime:
private readonly IHostApplicationLifetime _hostApplicationLifetime;
private readonly ILogger<Worker> _logger;
public Worker(IHostApplicationLifetime hostApplicationLifetime, ILogger<Worker> logger)
{
_hostApplicationLifetime = hostApplicationLifetime;
_logger = logger;
}
And then in ExecuteAsync in , After processing the business logic that must be completed before exiting , Manual call IHostApplicationLifetime Of StopApplication Method , Here's the rich ExecuteAsync Code :
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
// Here is the actual business logic
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("Exiting application...");
GetOffWork(stoppingToken); // Work to be done before closing
_hostApplicationLifetime.StopApplication(); // Manual call StopApplication
}
}
private async Task SomeMethodThatDoesTheWork(CancellationToken cancellationToken)
{
_logger.LogInformation(" I love work , Hard work ing……");
await Task.CompletedTask;
}
/// <summary>
/// Work to be done before closing
/// </summary>
private void GetOffWork(CancellationToken cancellationToken)
{
_logger.LogInformation(" ah , too bad , There's an emergency bug It needs to be done by the end of the day !!!");
_logger.LogInformation(" Ah ah , I love working overtime , I'm going to do it again 20 second ,Wait 1 ");
Task.Delay(TimeSpan.FromSeconds(20)).Wait();
_logger.LogInformation(" aaahhhhhhh , I love working overtime , I'm going to do it again 1 minute ,Wait 2 ");
Task.Delay(TimeSpan.FromMinutes(1)).Wait();
_logger.LogInformation(" Ah ha ha ha ha ha , It's finally over , Leave after work !");
}
here , Again dotnet run Operation service , Then press CTRL+C Key to turn off the service , You will find the work to be done before closing GetOffWork It will not exit the service until the operation is completed .
thus , We've done that Worker Service Elegant exit .
StartAsync and StopAsync
To learn more about Worker Service, Let's enrich our code , Override base class BackgroundService Of StartAsync and StopAsync Method :
public class Worker : BackgroundService
{
private bool _isStopping = false; // Whether it's stopping working
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)
{
_logger.LogInformation(" go to work , It's another energetic day ,output from StartAsync");
return base.StartAsync(cancellationToken);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
// Here is the actual business logic
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("Exiting application...");
GetOffWork(stoppingToken); // Work to be done before closing
_hostApplicationLifetime.StopApplication(); // Manual call StopApplication
}
}
private async Task SomeMethodThatDoesTheWork(CancellationToken cancellationToken)
{
if (_isStopping)
_logger.LogInformation(" Pretend you're still working hard ing…… Actually, I went to wash the cups ");
else
_logger.LogInformation(" I love work , Hard work ing……");
await Task.CompletedTask;
}
/// <summary>
/// Work to be done before closing
/// </summary>
private void GetOffWork(CancellationToken cancellationToken)
{
_logger.LogInformation(" ah , too bad , There's an emergency bug It needs to be done by the end of the day !!!");
_logger.LogInformation(" Ah ah , I love working overtime , I'm going to do it again 20 second ,Wait 1 ");
Task.Delay(TimeSpan.FromSeconds(20)).Wait();
_logger.LogInformation(" aaahhhhhhh , I love working overtime , I'm going to do it again 1 minute ,Wait 2 ");
Task.Delay(TimeSpan.FromMinutes(1)).Wait();
_logger.LogInformation(" Ah ha ha ha ha ha , It's finally over , Leave after work !");
}
public override Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation(" Great , It's time to get off work ,output from StopAsync at: {time}", DateTimeOffset.Now);
_isStopping = true;
_logger.LogInformation(" Go wash the tea cup first ……", DateTimeOffset.Now);
Task.Delay(30_000).Wait();
_logger.LogInformation(" The cup is ready .", DateTimeOffset.Now);
_logger.LogInformation(" After work ^_^", DateTimeOffset.Now);
return base.StopAsync(cancellationToken);
}
}
Run it again
dotnet build
dotnet run
Then press CTRL+C Key to turn off the service , Look at the results of the run ?
We can observe that in Worker Service On and off , Base class BackgroundService The running order of the three methods that can be overridden in is shown in the figure below :


summary
In this paper , I introduced how to exit gracefully through an example Worker Service Knowledge about .
Worker Service It's still essentially a console application , Perform a job . But it can not only run directly as a console application , You can also use sc.exe The utility is installed as Windows service , It can also be deployed to linux Running as a background process on the machine . I'll tell you more about Worker Service Knowledge .
边栏推荐
- 【深入理解TcaplusDB技术】TcaplusDB业务数据备份
- Uncover ges super large scale graph computing engine hyg: Graph Segmentation
- 中断操作:AbortController学习笔记
- Slam visuel Leçon 14 leçon 9 filtre Kalman
- Handling method of qstring containing "\u0000" in QT
- Virtual machine class loading mechanism
- 踩坑记录---线程池拒绝策略引起的一系列巧合
- Mobile heterogeneous computing technology - GPU OpenCL programming (basic)
- Which of the top ten securities companies has the lowest commission? Is it safe to open an account
- Three traversal methods of binary tree (recursive + non recursive) complete code
猜你喜欢

【深入理解TcaplusDB技术】TcaplusDB构造数据

What is an operator?

Chapter 4:win10 installing mingw64

What is an operator?

解决nvprof 报错ERR_NVGPUCTRPERM - The user does not have permission to profile on the target device.
![存在重复元素III[利用排序后的有序性进行剪枝]](/img/26/5c3632a64945ea3409f8240ef5b18a.png)
存在重复元素III[利用排序后的有序性进行剪枝]

What is an operator?

ASP.NET超市便利店在线购物商城源码,针对周边配送系统

Mobile heterogeneous computing technology - GPU OpenCL programming (basic)

跨境电商亚马逊、eBay、Shopee、Lazada、速卖通、沃尔玛、阿里国际等平台,怎样进行自养号测评更安全?
随机推荐
Fixed frequency and voltage regulation scheme of Qi v1.2.4 protocol
延时函数如何延时
Kotlin of Android cultivation manual - several ways to write a custom view
Encryption trend: Fashion advances to the meta universe
篇6:CLion:Toolchains are not configured Configure Disable profile
SQL Server real time backup library requirements
IVX 启航
Indexes
篇5:VS2017搭建QT5.9.9开发环境
十大券商的排名是?手机开户安全么?
20 provinces and cities announce the road map of the meta universe
什么是算子?
SDN system method | 9 Access network
[machine learning] case study of college entrance examination prediction based on multiple time series
ASP.NET超市便利店在线购物商城源码,针对周边配送系统
Slam visuel Leçon 14 leçon 9 filtre Kalman
Are the top ten leading securities companies safe to open accounts
安装spark + 用命令运行scala相关项目 + crontab定时执行
【深入理解TcaplusDB技术】一键安装Tmonitor后台
怎么判断自己是否适合转行软件测试