【问题标题】:How to cancel webhost when process is stopping进程停止时如何取消虚拟主机
【发布时间】:2020-11-14 19:01:00
【问题描述】:

我刚刚尝试在模板化 Web 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);
}

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

提前感谢您的任何提示!

【问题讨论】:

    标签: c# .net asynchronous asp.net-web-api cancellation-token


    【解决方案1】:

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

    IHostLifetime 的现有实现包括consolewindows servicesystemd。这基本上是 UseWindowsServiceUseSystemd 扩展注册的内容,参见例如WindowServiceLifetimeHostBuilderExtensions source。生命周期实现通常使用IHostApplicationLifetime 来关闭应用程序。默认的 Web 主机设置包括控制台生命周期。

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

    在任何运行时关闭事件(例如UnhandledExceptionProcessExit)中注册取消侦听器是不必要的,因为无论如何应用程序进程都会被拆除。托管概念是基于基于任务的异步,它不会产生任何后续进程或类似资源,这些资源会在Main 退出后保持活动状态。

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

    【讨论】:

      【解决方案2】:

      我刚刚发现这个UseConsoleLifetime()可以在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>());
      }
      

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

      【讨论】:

        猜你喜欢
        • 2012-07-05
        • 1970-01-01
        • 1970-01-01
        • 2022-11-02
        • 1970-01-01
        • 2013-07-12
        • 1970-01-01
        • 2015-12-30
        • 1970-01-01
        相关资源
        最近更新 更多