如何在ASP.NET Core应用关闭前执行逻辑?寻求内置解决方案
ASP.NET Core 跟踪应用关闭事件的内置解决方案
当然有内置解决方案,完全可以通过依赖注入集成的方式实现应用关闭前的逻辑执行,以下是两种最常用的方案:
1. 利用 IHostApplicationLifetime 监听全局关闭事件
IHostApplicationLifetime 是ASP.NET Core宿主提供的内置接口,专门用于监听应用的启动、关闭生命周期事件。你可以在BackgroundService中注入它,注册ApplicationStopping或ApplicationStopped事件来执行清理逻辑:
示例代码
public class GlobalShutdownService : BackgroundService { private readonly IHostApplicationLifetime _appLifetime; private readonly ILogger<GlobalShutdownService> _logger; public GlobalShutdownService(IHostApplicationLifetime appLifetime, ILogger<GlobalShutdownService> logger) { _appLifetime = appLifetime; _logger = logger; } protected override Task ExecuteAsync(CancellationToken stoppingToken) { // 监听应用开始关闭的事件(触发于关闭流程启动时) _appLifetime.ApplicationStopping.Register(() => { _logger.LogInformation("应用启动关闭流程,执行全局清理逻辑..."); // 这里编写你的同步清理逻辑:释放资源、缓存持久化、通知外部服务等 // 注意:此操作需尽量快速,避免阻塞关闭流程 }); // 监听应用完全关闭的事件(触发于所有服务停止后) _appLifetime.ApplicationStopped.Register(() => { _logger.LogInformation("应用已完成关闭,执行最终收尾逻辑..."); }); // 保持BackgroundService运行,直到收到停止信号 return Task.Delay(Timeout.Infinite, stoppingToken); } }
注册服务
在Program.cs中添加托管服务注册:
builder.Services.AddHostedService<GlobalShutdownService>();
2. 重写 BackgroundService 的 StopAsync 方法
如果你的清理逻辑属于某个特定托管服务自身的资源释放,直接重写BackgroundService的StopAsync方法更直观——应用关闭时,宿主会自动调用所有托管服务的StopAsync方法:
示例代码
public class TaskCleanupService : BackgroundService { private readonly ILogger<TaskCleanupService> _logger; public TaskCleanupService(ILogger<TaskCleanupService> logger) { _logger = logger; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { // 托管服务的主运行逻辑(示例:定时任务) while (!stoppingToken.IsCancellationRequested) { _logger.LogInformation("后台任务正在运行..."); await Task.Delay(3000, stoppingToken); } } public override async Task StopAsync(CancellationToken cancellationToken) { _logger.LogInformation("应用关闭,执行任务服务的清理逻辑..."); // 执行异步清理操作:终止当前任务、保存任务状态、关闭连接等 await FinishPendingTasksAsync(cancellationToken); await base.StopAsync(cancellationToken); } private async Task FinishPendingTasksAsync(CancellationToken cancellationToken) { // 模拟异步清理过程 await Task.Delay(1500, cancellationToken); _logger.LogInformation("任务服务清理完成"); } }
注册服务
同样在Program.cs中注册:
builder.Services.AddHostedService<TaskCleanupService>();
注意事项
- 超时控制:宿主默认有5秒的关闭超时时间,若你的清理逻辑耗时较长,可通过配置
HostOptions延长超时:builder.Services.Configure<HostOptions>(options => { options.ShutdownTimeout = TimeSpan.FromSeconds(10); }); - 事件触发场景:以上方案可以捕获绝大多数关闭场景,包括控制台按
Ctrl+C、Docker容器停止、IIS应用池回收、系统关机等。
内容的提问来源于stack exchange,提问作者Firuz
相关产品推荐
相关产品推荐

