进程停止时如何取消虚拟主机

How to cancel webhost when process is stopping

我刚刚尝试在模板化网络 API (dotnet 5) 中使用 async Task Main 方法。这是我的样板代码:

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>());
}

我注意到 RunAsync 使用取消令牌,我希望它基于应用程序关闭。

我的问题 - 在此处设置链接回进程关闭的取消令牌的正确(标准)方法是什么?

我可以这样做:

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);
}

但想知道是否有我缺少的更标准的方法。

提前感谢您的提示!

.NET 主机设计将基于外部事件(例如控制台应用程序中的 CTRL + C)终止应用程序的逻辑放入 IHostLifetime 接口的实现中。

IHostLifetime 的现有实施包括 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 以关闭应用程序。默认的 Web 主机设置包括控制台生命周期。

使用这种方法,可以将单个应用程序配置为控制台应用程序、windows 服务,或使用所需的任何其他关闭触发器。

没有必要将取消侦听器注册到任何运行时关闭事件,例如 UnhandledExceptionProcessExit,因为应用程序进程无论如何都会被拆除。托管概念基于基于任务的异步,它不会产生任何后续进程或类似资源,这些进程或类似资源将在 Main.

退出后保持活动状态

有关详细信息,请参阅 Web Host and Generic Host 文档页面。

我刚刚发现这个 UseConsoleLifetime() 可以在 webHost 构建器上设置:

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>());
}

现在 Microsoft.Hosting.LifeTime 为我处理取消令牌。太棒了!