You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 12:20:40