简体   繁体   English

使用 .NET 通用主机的控制台应用程序过早退出

[英]Console application using .NET Generic Host exits too early

I'm trying to add console commands to an existing ASP.NET Core 5 web application.我正在尝试向现有的 ASP.NET Core 5 Web 应用程序添加控制台命令。 The important part here is that I can set up all the dependency injection and configuration that is in the web application and use it in the console application as well.这里的重要部分是我可以设置 Web 应用程序中的所有依赖注入和配置,并在控制台应用程序中使用它。 To do that I'm using the .NET Generic host in the following way:为此,我以以下方式使用 .NET 通用主机:

public class ConsoleHostedService : IHostedService
{
    private readonly IHostApplicationLifetime appLifetime;

    public ConsoleHostedService(IHostApplicationLifetime appLifetime)
    {
      this.appLifetime = appLifetime;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
      appLifetime.ApplicationStarted.Register(() =>
      {
        Task.Run(async () =>
          {
            try {
         
              Console.WriteLine("1");
              await Task.Delay(1000);
              Console.WriteLine("2");
            }
            catch (Exception ex)
            {
              Console.WriteLine(ex.ToString());
            }
            finally
            {
              // Stop the application once the work is done
              appLifetime.StopApplication();
            }
          });
      });

      return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
      return Task.CompletedTask;
    }

  }
}

This Host is executed from the following code:该主机由以下代码执行:

public static void ExecuteCommand(string[] args)
    {
      Parser.Default.ParseArguments<CommandOptions1, CommandOptions2>(args)
        .WithParsed<CommandOptions1>(async options =>
        {
          try
          {
            await Host.CreateDefaultBuilder(args)
              .ConfigureServices((hostContext, services) =>
              {
                // configuration of dependency injection here

                services.AddHostedService<ConsoleHostedService>();
              })
              .RunConsoleAsync();
          }
          catch (Exception e)
          {
            Console.WriteLine(e);
          }
        })
        .WithParsed<CommandOptions2>(o =>
        {
          // different command here
        });
    }
  }

I'm using the CommandLineParser library here, though this part shouldn't matter for the problem.我在这里使用的是CommandLineParser库,尽管这部分对于问题来说无关紧要。 The actual generic host code was adapted from this blog post , which did seem to adress exactly what I needed.实际的通用主机代码改编自这篇博客文章,它似乎确实满足了我的需要。

The Problem is that the console application exits early, in my example where the await Task.Delay(1000) stands as a placeholder for my actual code I added some logging.问题是控制台应用程序提前退出,在我的示例中, await Task.Delay(1000)代表我的实际代码的占位符,我添加了一些日志记录。 The first line "1" is written to the console, the second line "2" is never written.第一行“1”写入控制台,第二行“2”从未写入。 I also get output for Microsoft.Hosting.Lifetime about the application stopping.我还获得了有关应用程序停止的 Microsoft.Hosting.Lifetime 输出。 The application seems to stop itself the moment it became ready, and any work I do in there that takes a bit of time is never executed at all.应用程序似乎在它准备就绪的那一刻就停止了,我在那里做的任何需要一点时间的工作都不会被执行。

I double checked all async/awaits and they're all there, the issue isn't a forgotten await.我仔细检查了所有异步/等待,它们都在那里,问题不是忘记等待。 It does seem to be something about the Generic Host or the Lifetime itself, but those parts are pretty much entirely taken from the blog post I linked.它似乎确实与通用主机或 Lifetime 本身有关,但这些部分几乎完全取自我链接的博客文章。 I looked over all parts here, but I can't see any reason why the code would just shut down immediately.我查看了此处的所有部分,但我看不出代码会立即关闭的任何原因。

Any idea what I'm doing wrong here, or what might cause the early shutdown?知道我在这里做错了什么,或者什么可能导致提前关闭?

Somewhere in the main console program it needs to know when to leave.在主控制台程序的某个地方,它需要知道什么时候离开。 Having it run an async call means that the program flow returns immediately after the setup call.让它运行异步调用意味着程序流在设置调用后立即返回。 Hence the console app is heading to the exit without waiting.因此,控制台应用程序无需等待即可前往出口。 You need to halt the console until the process ends.您需要暂停控制台,直到该过程结束。

In the main console app do something like:在主控制台应用程序中执行以下操作:

Task.WaitAll( {the task(s) launched by the app} );

So the main program will halt its process execution flow while the other async processes run and smart wait until all of those task(s) are finished.因此,主程序将停止其进程执行流程,而其他异步进程运行并智能等待,直到所有这些任务完成。

Or have some type of signal process to be sent when the async process ends and have the app check for that and shut down after it gets that event.或者在异步进程结束时发送某种类型的信号进程,并让应用程序检查并在收到该事件后关闭。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 有没有一种方法可以使用通用主机将调试秘密从asp.net控制台应用程序传递给docker容器? - Is there a way to pass debug secrets to a docker container from a asp.net console application using generic host? 个别任务过早退出 - Individual Task exits too early 如何使用通用主机生成器运行 .NET Core 控制台应用程序 - How to run .NET Core Console app using generic host builder .NET Core:如何在控制台应用程序中为 .NET 通用主机配置 JSON 库? - .NET Core: How to configure JSON library for .NET Generic Host in console application? 如何使用 Z303CB0EF9EDB9082AZ61BBBE582 将 REST API 添加到用 .NET Framework 4.8 编写的控制台应用程序中? - How to add REST API to console app written in .NET Framework 4.8 using .NET generic host? 如何使用控制台应用程序中的通用主机从 appsettings 中获取连接字符串? - How do I get the connection string out of appsettings using a generic host in console application? 如何使用通用主机 (HostBuilder) 为 .NET Core 控制台应用程序设置托管环境名称 - How to set hosting environment name for .NET Core console app using Generic Host (HostBuilder) 即使在 .NET Core 控制台应用程序中使用 Console.ReadLine() docker 容器也会立即退出 - docker container exits immediately even with Console.ReadLine() in a .NET Core console application 将 Autofac 与 ASP.Net Core 3.1 通用主机“Worker Service”应用程序一起使用 - Using Autofac with ASP.Net Core 3.1 generic host "Worker Service" application .NET 通用主机:防止应用程序因未处理的异常而崩溃 - .NET Generic Host : Prevent application crash on unhandled exception
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM