[英]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.