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();
}