Igo*_*ues 3 .net c# dependency-injection background-service winforms
我正在尝试启动分配给IHostBuilder的services.HostedService的BackgroundService。
IHostBuilder定义:
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();
}
);
});
}
Run Code Online (Sandbox Code Playgroud)
但我发现启动HostedService 的唯一可能的方法是运行以下命令:
await CreateHostBuilder().Build().RunAsync();
Run Code Online (Sandbox Code Playgroud)
最后,问题发生是因为在这种方法中,线程锁定在该行上,并且不允许我运行公共块代码来启动表单本身:
Application.Run(new MainForm());
Run Code Online (Sandbox Code Playgroud)
如果我先运行表单,也会发生同样的情况,线程会锁定该行,并且不会让我调用HostBuilder的RunAsync。
我还尝试在 Form 类上声明所有HostBuilder范围,并在其构造函数上启动BackgroundService,但随后我将无法在 ctor 上运行 Async 方法。
我目前正在尝试(但尚未成功)的是在没有Application.Run 的情况下调用表单(并且仍然不知道这样做的所有副作用),以便我接下来可以运行HostBuilder。
我现在的整个课程:
static class Program
{
[STAThread]
private static async Task Main()
{
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var host = CreateHostBuilder().Build();
host.Services.GetRequiredService<AuthenticationForm>().Show();
await host.RunAsync();
}
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();
}
);
});
}
}
Run Code Online (Sandbox Code Playgroud)
考虑到.NET 5并忽略BackgroundWorker组件,解决方法是什么?
Nkosi 的解决方案,评论:
当您运行主机时,创建另一个托管服务以这种方式调用
Application.Run,UI 方面和后台工作托管服务将启动
class StartProgram : BackgroundService
{
private readonly IServiceProvider _services;
public StartProgram(IServiceProvider services)
{
this._services = services;
}
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run((AuthenticationForm)_services.GetService(typeof(AuthenticationForm)));
return Task.CompletedTask;
}
}
Run Code Online (Sandbox Code Playgroud)
和 Program.cs:
static class Program
{
[STAThread]
private static async Task Main()
{
await CreateHostBuilder().Build().RunAsync();
}
private static IHostBuilder CreateHostBuilder()
{
return Host.CreateDefaultBuilder()
.ConfigureServices(services =>
{
services.AddHostedService<LicenseControl>();
services.AddHostedService<StartProgram>();
#region ETC...
});
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2538 次 |
| 最近记录: |