Reputation: 7217
I've just tried using the async Task Main
method in a templated web API (dotnet 5). Here's my boiler plate code:
public class Program
{
public static async Task Main(string[] args)
{
await CreateHostBuilder(args).Build().RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>());
}
I noticed that the RunAsync takes a cancellation token and I'd like that to be based on the application closing.
My question - what's the correct (standard) way to setup a cancellation token here that's linked back to the process shutdown?
I could do something like this:
public static async Task Main(string[] args)
{
var cts = new CancellationTokenSource();
AppDomain.CurrentDomain.UnhandledException += (s, e) => { if (e.IsTerminating) cts.Cancel(); };
AppDomain.CurrentDomain.ProcessExit += (s, e) => cts.Cancel();
Console.CancelKeyPress += (s, e) => { e.Cancel = true; cts.Cancel(); };
await CreateHostBuilder(args).Build().RunAsync(cts.Token);
}
But wondered if there's a more standard approach that I'm missing.
Thanks for any tips in advance!
Upvotes: 2
Views: 1969
Reputation: 7217
I just found this UseConsoleLifetime()
that can be set on the webHost builder:
public class Program
{
public static async Task Main(string[] args)
{
await CreateHostBuilder(args).Build().RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseConsoleLifetime()
.ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>());
}
Now Microsoft.Hosting.LifeTime
handles the cancellation token for me. Great!
Upvotes: 1
Reputation: 2913
.NET host design puts the logic to terminate the application based on external events (e.g. CTRL + C in console app) into an implementation of IHostLifetime interface.
Existing implementations of IHostLifetime
include console, windows service and systemd. This is basically what UseWindowsService
and UseSystemd
extensions register, see e.g. WindowServiceLifetimeHostBuilderExtensions source. The lifetimes implementations typically use IHostApplicationLifetime to shut down the application. The default web host setup includes the console lifetime.
Using this approach, a single application can be configured as a console app, windows service, or use whatever other shutdown triggers required.
It should not be otherwise necessary to register the cancellation listener to any runtime shutdown events such as UnhandledException
or ProcessExit
as the application process is getting torn down anyway. The hosting concept is a based on Task-based asynchrony, it does not spawn any subsequent processes or similar resources that would stay alive beyond the exit of Main
.
For more details, see Web Host and Generic Host documentation pages.
Upvotes: 4