.NET Core 3.0 使用 IHostApplicationLifetime 处理应用启动和停止事件
IHostedService
该接口中有两个方法:
StartAsync:当应用程序主机准备启动服务时触发
StopAsync:当应用程序主机准备停止服务时触发
//
// 摘要:
// /// Defines methods for objects that are managed by the host. ///
public interface IHostedService
{
//
// 摘要:
// /// Triggered when the application host is ready to start the service. ///
//
// 参数:
// cancellationToken:
// Indicates that the start process has been aborted.
Task StartAsync(CancellationToken cancellationToken);
//
// 摘要:
// /// Triggered when the application host is performing a graceful shutdown. ///
//
// 参数:
// cancellationToken:
// Indicates that the shutdown process should no longer be graceful.
Task StopAsync(CancellationToken cancellationToken);
}
IHostApplicationLifetime
该接口中包含三个属性:Host程序的启动、正在停止、已停止,一个方法StopApplication,该方法用于主动停止程序。
//
// 摘要:
// /// Allows consumers to be notified of application lifetime events. ///
public interface IHostApplicationLifetime
{
//
// 摘要:
// /// Triggered when the application host has fully started. ///
CancellationToken ApplicationStarted
{
get;
}
//
// 摘要:
// /// Triggered when the application host is performing a graceful shutdown. ///
// Shutdown will block until this event completes. ///
CancellationToken ApplicationStopped
{
get;
}
//
// 摘要:
// /// Triggered when the application host is performing a graceful shutdown. ///
// Shutdown will block until this event completes. ///
CancellationToken ApplicationStopping
{
get;
}
//
// 摘要:
// /// Requests termination of the current application. ///
void StopApplication();
}
这里实现IHostedService接口,然后使用IHostApplicationLifetime(该接口由框架自动实现注入),在IHostedService的StartAsync方法中注册IHostApplicationLifetime中的三个程序运行事件,可以做一些自定义的操作,我这里只是记录了日志。
internal class LifetimeEventsHostedService : IHostedService
{
private readonly string appCode = ConfigurationManager.GetAppSetting("AppCode");
private readonly string appName = ConfigurationManager.GetAppSetting("AppName");
private readonly IHostApplicationLifetime _appLifetime;
public LifetimeEventsHostedService(IHostApplicationLifetime appLifetime)
{
_appLifetime = appLifetime;
}
public Task StartAsync(CancellationToken cancellationToken)
{
_appLifetime.ApplicationStarted.Register(OnStarted);
_appLifetime.ApplicationStopping.Register(OnStopping);
_appLifetime.ApplicationStopped.Register(OnStopped);
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
private void OnStarted()
{
var interNetworkV6 = System.Net.Sockets.AddressFamily.InterNetworkV6;
var interNetwork = System.Net.Sockets.AddressFamily.InterNetwork;
var ipList = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()
.Select(p => p.GetIPProperties())
.SelectMany(p => p.UnicastAddresses)
.Where(p => (p.Address.AddressFamily == interNetwork || p.Address.AddressFamily == interNetworkV6) && !System.Net.IPAddress.IsLoopback(p.Address)).ToList();
Console.WriteLine($"OnStarted has been called:【{appCode}】【{appName}】【{DateTime.Now}】 【{ipList[1].Address}】 【{ipList[0].Address}】");
Logger.Info($"OnStarted has been called:【{appCode}】【{appName}】【{DateTime.Now}】 【{ipList[1].Address}】 【{ipList[0].Address}】");
}
private void OnStopping()
{
Console.WriteLine($"OnStopping has been called:【{appCode}】【{appName}】【{DateTime.Now}】");
Logger.Info($"OnStopping has been called:【{appCode}】【{appName}】【{DateTime.Now}】");
}
private void OnStopped()
{
Console.WriteLine($"OnStopped has been called:【{appCode}】【{appName}】【{DateTime.Now}】");
Logger.Info($"OnStopped has been called:【{appCode}】【{appName}】【{DateTime.Now}】");
}
}
最后在服务中注入
.ConfigureServices(a =>
{
a.AddSingleton<IHostedService, LifetimeEventsHostedService>();
});
也可以不使用IHostedService进行承载,直接使用IHostApplicationLifetime进行注册
internal static class RegisterLifetimeEvents
{
private static readonly string appCode = ConfigurationManager.GetAppSetting("AppCode");
private static readonly string appName = ConfigurationManager.GetAppSetting("AppName");
private static readonly string iPV4Address;
private static readonly string iPV6Address;
static RegisterLifetimeEvents()
{
var interNetworkV6 = AddressFamily.InterNetworkV6;
var interNetwork = AddressFamily.InterNetwork;
var ipList = NetworkInterface.GetAllNetworkInterfaces()
.Select(p => p.GetIPProperties())
.SelectMany(p => p.UnicastAddresses)
.Where(p => (p.Address.AddressFamily == interNetwork || p.Address.AddressFamily == interNetworkV6) && !System.Net.IPAddress.IsLoopback(p.Address)).ToList();
iPV4Address = ipList[1]?.Address.ToString();
iPV6Address = ipList[0]?.Address.ToString();
}
/// <summary>
/// 注册应用程序生命周期事件
/// </summary>
public static void RegisterApplicationLifetimeEvents(this IHost host)
{
var hostApplicationLifetime = host.Services.GetService<IHostApplicationLifetime>();
hostApplicationLifetime.ApplicationStarted.Register(OnStarted);
hostApplicationLifetime.ApplicationStopping.Register(OnStopping);
hostApplicationLifetime.ApplicationStopped.Register(OnStopped);
}
private static void OnStarted()
{
Console.WriteLine($"OnStarted has been called:{appCode} {appName} {DateTime.Now} {iPV4Address} {iPV6Address}");
Logger.Info($"OnStarted has been called:{appCode} {appName} {DateTime.Now} {iPV4Address} {iPV6Address}");
}
private static void OnStopping()
{
Console.WriteLine($"OnStopping has been called:{appCode} {appName} {DateTime.Now} {iPV4Address} {iPV6Address}");
Logger.Info($"OnStopping has been called:{appCode} {appName} {DateTime.Now} {iPV4Address} {iPV6Address}");
}
private static void OnStopped()
{
Console.WriteLine($"OnStopped has been called:{appCode} {appName} {DateTime.Now} {iPV4Address} {iPV6Address}");
Logger.Info($"OnStopped has been called:{appCode} {appName} {DateTime.Now} {iPV4Address} {iPV6Address}");
}
}
在Main函数中注册一下即可
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
host.RegisterApplicationLifetimeEvents();
host.Run();
}