C# 如何以编程方式停止/退出/终止dotnet core HostBuilder控制台应用程序?

C# 如何以编程方式停止/退出/终止dotnet core HostBuilder控制台应用程序?,c#,.net-core,console-application,C#,.net Core,Console Application,我正在尝试创建一个dotnet核心控制台应用程序。该应用程序是一个简单实用的应用程序,应该启动,做它的事情,然后退出。 使用VisualStudio生成的标准控制台应用程序模板很容易实现。 但是现在我们有了HostBuilder,它似乎更具吸引力,因为它带来了WebHostBuilder、DI、Loggin等的统一体验 但这种方法似乎只针对长期运行的后台服务而设计。它将启动并一直保持,直到外部终止事件(如Ctrl-C)发生 有没有办法从内部结束这种类型的应用程序?您可以使用IHostApplic

我正在尝试创建一个dotnet核心控制台应用程序。该应用程序是一个简单实用的应用程序,应该启动,做它的事情,然后退出。 使用VisualStudio生成的标准控制台应用程序模板很容易实现。 但是现在我们有了HostBuilder,它似乎更具吸引力,因为它带来了WebHostBuilder、DI、Loggin等的统一体验

但这种方法似乎只针对长期运行的后台服务而设计。它将启动并一直保持,直到外部终止事件(如Ctrl-C)发生


有没有办法从内部结束这种类型的应用程序?

您可以使用
IHostApplicationLifetime
停止运行应用程序,您可以从构造函数访问它并调用
StopApplication()
方法

IHostApplicationLifetime _lifeTime;
public MyClass(IHostApplicationLifetime lifeTime)
{
    _lifeTime = lifeTime;
}
然后停止应用程序()


已编辑以使用
IHostApplicationLifetime
,因为
IApplicationLifetime
不受欢迎。

即使您使用注册应用程序中的所有依赖项,也不必使用来执行cmd行应用程序。您可以通过创建如下服务范围来执行应用程序:

var hostbuilder = new HostBuilder();
builder.ConfigureServices(ConfigureServices); //Configure all services for your application here
var host = hostbuilder.Build();

using (var scope = host.Services.CreateScope())
{
   var myAppService = scope.ServiceProvider.GetRequiredService<IMyAppServiceToRun>(); //Use IHost DI container to obtain instance of service to run & resolve all dependencies

   await myAppService.StartAsync(); // Execute your task here
}

using (host)
    host.StopAsync();
var hostbuilder=new hostbuilder();
builder.ConfigureServices(ConfigureServices)//在此处配置应用程序的所有服务
var host=hostbuilder.Build();
使用(var scope=host.Services.CreateScope())
{
var myAppService=scope.ServiceProvider.GetRequiredService();//使用IHost DI容器获取服务实例以运行和解析所有依赖项
等待myAppService.StartAsync();//在此处执行任务
}
使用(主机)
StopAsync();

1-在
Program.cs中构建主机时,使用
UseConsoleLifetime()

Program.cs:


2-已注册的
应用程序已停止
事件。因此,您可以通过调用当前进程的
Kill()
方法来暴力终止应用程序

Startup.cs:


我也有同样的问题。我需要终止我的web服务。因此,我使用了类似于标有答案的解决方案的方法,但服务并没有立即终止,他继续使用命令。所以我需要在出口后马上回来

我的杀人方法:

private void Exit(IHostApplicationLifetime lifetime, ExitCode code)
{
    Environment.ExitCode = (int)code; //just shows in debug
    lifetime.StopApplication();
    // add log if you want to see the exitCode
}
Startup.cs中的Configure方法

public void Configure(IApplicationBuilder app, IHostApplicationLifetime lifetime)
{
    // code
    bool hasPendingMigrations = HasDatabasePendingMigrations(app);
    if (hasPendingMigrations)
    {
        Exit(lifetime, ExitCode.HasPendingMigrations);
        // we need to return explicit after exit
        return;
    }
    // code
}
你需要回来。
ExitCode是一个自定义创建的枚举。

如果有人想知道IApplicationLifetime在本例中来自何处,您需要为此使用DI。使用HostBuilder,您可以使用ConfigureService进行设置,例如通过向ServiceCollection.AddHostedService注册IHostedService的实现。然后,从该级别进一步注入的任何内容都将得到相应的处理,并且像IApplicationLifetime这样的框架内容将从盒子中取出,这样您就不必手动将其添加到容器中。“此类型已过时,将在将来的版本中删除。推荐的替代方案是Microsoft.Extensions.Hosting.IHostApplicationLifetime。“当我在控制台中调用_applicationLifetime.StopApplication()时,会写入“应用程序正在关闭…”,但代码继续执行,并在以下代码中很快出现异常时失败:(@Gondil同样的问题,你找到了解决方案吗?@Gondil很高兴发现了我自己。我刚在退出后返回,以避免任何正在进行的命令。使用上面提到的
iaapplicationlifetime.stopplication()
怎么样?UseConsoleLifetime为你做了什么?你是否应该同时使用这两个命令?
public void Configure(IHostApplicationLifetime appLifetime) {
 appLifetime.ApplicationStarted.Register(() => {
  Console.WriteLine("Press Ctrl+C to shut down.");
 });

 appLifetime.ApplicationStopped.Register(() => {
  Console.WriteLine("Terminating application...");
  System.Diagnostics.Process.GetCurrentProcess().Kill();
 });
}
private void Exit(IHostApplicationLifetime lifetime, ExitCode code)
{
    Environment.ExitCode = (int)code; //just shows in debug
    lifetime.StopApplication();
    // add log if you want to see the exitCode
}
public void Configure(IApplicationBuilder app, IHostApplicationLifetime lifetime)
{
    // code
    bool hasPendingMigrations = HasDatabasePendingMigrations(app);
    if (hasPendingMigrations)
    {
        Exit(lifetime, ExitCode.HasPendingMigrations);
        // we need to return explicit after exit
        return;
    }
    // code
}