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

.NET5中如何让Winforms结合BackgroundService与依赖注入运行?

解决方案

你遇到的阻塞问题核心原因是IHost.RunAsync()会一直等待宿主进程终止才返回,而Application.Run()同样会阻塞直到UI窗体关闭,二者默认都会占用当前线程,只要调整启动顺序和调用方法即可解决:

核心改动点

不要调用RunAsync(),改用StartAsync()启动宿主:StartAsync()只会完成所有托管服务(包括你注册的BackgroundService)的启动流程就立即返回,不会阻塞当前线程,等UI窗体关闭后再手动调用StopAsync()优雅关闭宿主即可。

完整修改后的Program类代码

static class Program
{
    [STAThread]
    private static async Task Main()
    {
        Application.SetHighDpiMode(HighDpiMode.SystemAware);
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);            

        // 构建宿主但不立即阻塞运行
        var host = CreateHostBuilder().Build();
        // 启动所有托管服务,启动完成后立即返回
        await host.StartAsync();

        try
        {
            // 从DI容器获取启动窗体,保证依赖注入正常生效
            var authForm = host.Services.GetRequiredService<AuthenticationForm>();
            // 启动UI消息循环,阻塞直到所有窗体关闭
            Application.Run(authForm);
        }
        finally
        {
            // 窗体关闭后优雅停止宿主,等待BackgroundService完成清理
            await host.StopAsync();
            // 释放宿主资源
            host.Dispose();
        }
    }
    
    // CreateHostBuilder方法不需要做任何修改,和你之前的实现完全一致
    private static IHostBuilder CreateHostBuilder()
    {
        return Host.CreateDefaultBuilder()
            .ConfigureServices(services =>
            {
                services.AddHostedService<LicenseControl>();

                services.AddTransient<Database>();
                services.AddTransient<CoreLicense>();

                services.AddSingleton<FormSelector>();

                services.AddTransient<ClienteForm>();
                services.AddTransient<GastoForm>();
                services.AddTransient<IngredienteForm>();
                services.AddTransient<ProdutoForm>();
                services.AddTransient<ReceitaForm>();
                services.AddTransient<RelatorioForm>();
                services.AddTransient<VendaForm>();
                services.AddTransient<MainForm>();
                services.AddTransient<ConfiguracoesForm>();
                services.AddTransient<UsuarioForm>();

                services.AddSingleton<AuthenticationForm>();
                
                services.AddScoped<IBridgeRepository, BridgeRepository>();
                services.AddScoped<IClienteRepository, ClienteRepository>();
                services.AddScoped<IGastoRepository, GastoRepository>();
                services.AddScoped<IIBGERepository, IBGERepository>();
                services.AddScoped<IIngredienteRepository, IngredienteRepository>();
                services.AddScoped<IProdutoRepository, ProdutoRepository>();
                services.AddScoped<IReceitaRepository, ReceitaRepository>();
                services.AddScoped<IVendaRepository, VendaRepository>();
                services.AddScoped<IUsuarioRepository, UsuarioRepository>();

                services.AddLogging(
                builder =>
                {
                    builder.AddFilter("Microsoft", LogLevel.Warning)
                           .AddFilter("System", LogLevel.Warning)
                           .AddFilter("NToastNotify", LogLevel.Warning)
                           .AddConsole();
                }
                );
            });
    }
}

方案说明

  1. 完全兼容.NET 5规范,不需要额外引入第三方组件,也不需要使用BackgroundWorker
  2. 依赖注入功能完全正常,所有窗体、服务的生命周期都由通用主机统一管理
  3. 退出逻辑优雅:用户关闭窗体后会自动通知BackgroundService停止,等待后台任务完成清理后再退出进程,不会出现后台任务被强制终止的问题

内容的提问来源于stack exchange,提问作者Igor Henriques

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 20:18:03