如何在ASP.Net Core 6应用中实现程序停止时执行的finally逻辑
.NET Core 6+ 实现应用关闭时的清理逻辑
在旧版.NET Core中,我们可以在Main方法的try-finally块里,让finally在应用关闭后执行清理操作。但.NET Core 6+采用顶级语句模式后,直接写try-finally会导致清理逻辑在应用启动前就执行(因为代码顺序执行,app.Run()是阻塞调用,之前的finally会先跑)。
以下是几种可行的解决方案:
方案1:手动显式定义Main方法
直接回到旧写法,显式编写Main方法,这样finally块会在app.Run()结束(应用关闭)后执行:
namespace YourAppNamespace; public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorPages(); SomeAPI someAPI = CreateSomeAPI(); try { someAPI.Connect(); var app = builder.Build(); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapRazorPages(); app.Run(); } catch (Exception ex) { Console.WriteLine($"发生异常:{ex.Message}"); } finally { someAPI.Disconnect(); } } private static SomeAPI CreateSomeAPI() => new SomeAPI(); }
方案2:利用IHostApplicationLifetime事件
这是.NET 6+推荐的方式,通过订阅应用生命周期事件,在启动时连接API,停止时断开:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorPages(); // 将SomeAPI注册为单例服务,方便后续获取 builder.Services.AddSingleton<SomeAPI>(_ => CreateSomeAPI()); var app = builder.Build(); // 获取应用生命周期服务 var lifetime = app.Services.GetRequiredService<IHostApplicationLifetime>(); var someAPI = app.Services.GetRequiredService<SomeAPI>(); // 应用启动完成后连接API lifetime.ApplicationStarted.Register(() => { try { someAPI.Connect(); Console.WriteLine("API连接成功"); } catch (Exception ex) { Console.WriteLine($"API连接失败:{ex.Message}"); // 连接失败可选择终止应用 lifetime.StopApplication(); } }); // 应用停止时执行断开操作 lifetime.ApplicationStopped.Register(() => { someAPI.Disconnect(); Console.WriteLine("API已断开连接"); }); // 中间件配置 app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapRazorPages(); app.Run();
方案3:使用using语句(若SomeAPI实现IDisposable)
如果SomeAPI实现了IDisposable接口,且Dispose方法中包含Disconnect逻辑,可以用using块自动管理生命周期:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorPages(); using var someAPI = CreateSomeAPI(); try { someAPI.Connect(); } catch (Exception ex) { Console.WriteLine($"API连接失败:{ex.Message}"); return; } var app = builder.Build(); // 中间件配置 app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapRazorPages(); app.Run(); // app.Run()阻塞结束后,using块会自动调用someAPI.Dispose(),完成断开操作
为什么原代码会失效?
原代码中finally块在app.Run()之前执行,因为代码是顺序执行的:先执行try里的Connect,接着进入finally执行Disconnect,最后才调用app.Run()启动应用,导致API还没被使用就已经断开了。
内容的提问来源于stack exchange,提问作者CribAd
相关产品推荐
相关产品推荐

