【问题标题】:Kestrel shutdown function in Startup.cs in ASP.NET CoreASP.NET Core 中 Startup.cs 中的 Kestrel 关闭功能
【发布时间】:2016-02-07 18:23:47
【问题描述】:

使用Microsoft.AspNet.Server.Kestrel时有关机功能吗? ASP.NET Core(以前的 ASP.NET vNext)显然有一个启动序列,但没有提及关闭序列以及如何处理干净关闭。

【问题讨论】:

    标签: c# asp.net-core


    【解决方案1】:

    在 ASP.NET Core 中,您可以注册到 IApplicationLifetime 提供的取消令牌

    public class Startup 
    {
        public void Configure(IApplicationBuilder app, IApplicationLifetime applicationLifetime) 
        {
            applicationLifetime.ApplicationStopping.Register(OnShutdown);
        }
    
        private void OnShutdown()
        {
             // Do your cleanup here
        }
    }
    

    IApplicationLifetime 还公开了 ApplicationStoppedApplicationStarted 的取消令牌以及用于停止应用程序的 StopApplication() 方法。

    对于 .NET Core 3.0+

    来自 cmets @Horkrine

    对于 .NET Core 3.0+,建议改用 IHostApplicationLifetime,因为 IApplicationLifetime 很快就会被弃用。其余的仍然可以像上面写的那样与新服务一起工作

    【讨论】:

    • 这应该适用于所有操作系统和服务器吗?我无法让它在 OSX + Kestrel 上运行。
    • 它应该适用于所有平台,否则可能是一个错误。 github上有一些老问题,也许你在github.com/aspnet/Hosting/issues/151尝试davidfowl的解决方法,否则尝试在github.com/aspnet/Hosting/issues打开一个问题可能是一个错误,它仍在RC1中为RC2做准备
    • @opiethehokie:也可能与github.com/aspnet/Hosting/issues/516有关。它适用于 linux,但据我所知,SIGINT 和 SIGTERM 也用于 MacOS。不够熟悉,不知道 MacOS 确实发送了哪些信号来停止进程。如果您使用的是 dnx core 1.0 还是针对完整的单声道框架,也可能会很有趣
    • 对于 Windows10、IIS 10 (Dev) 我正在启动 Start 工作,但没有发出优雅的停止信号。使用 Shift-F5 终止调试或通过系统托盘应用程序停止 IIS10 中的进程都是这种情况。
    • 对于 .NET Core 3.0+,建议使用IHostApplicationLifetime,因为IApplicationLifetime 很快就会被弃用。其余的仍将按照上面的说明与新服务一起工作
    【解决方案2】:

    除了原始答案之外,我在尝试在构造函数中连接 IApplicationLifetime 时遇到错误。

    我通过这样做解决了这个问题:

    public class Startup 
    {
        public void Configure(IApplicationBuilder app) 
        {
            var applicationLifetime = app.ApplicationServices.GetRequiredService<IApplicationLifetime>();
            applicationLifetime.ApplicationStopping.Register(OnShutdown);
        }
    
        private void OnShutdown()
        {
             // Do your cleanup here
        }
    }
    

    【讨论】:

    • 当您从 main 手动配置您的虚拟主机时,这无需使用 Startup 类即可工作。
    【解决方案3】:

    该类现已废弃,请参考新接口IHostApplicationLifetime。更多信息here

    【讨论】:

      【解决方案4】:

      我通过应用程序生命周期回调事件解决了这个问题

      Startup.cs

      public void Configure(IHostApplicationLifetime appLifetime) {
       appLifetime.ApplicationStarted.Register(() => {
        Console.WriteLine("Press Ctrl+C to shut down.");
       });
      
       appLifetime.ApplicationStopped.Register(() => {
        Console.WriteLine("Terminating application...");
        System.Diagnostics.Process.GetCurrentProcess().Kill();
       });
      }
      

      Program.cs

      另外,在构建主机时使用UseConsoleLifetime()

      Host.CreateDefaultBuilder(args).UseConsoleLifetime(opts => opts.SuppressStatusMessages = true);
      

      【讨论】:

      • 你应该在appLifetime.ApplicationStopped.Register做什么?我不明白这有什么帮助。假设你在控制器中有一个未知的当前正在进行的请求,它可以是 1、10 或 1000,你不知道。你希望他们都完成。这种方法有什么帮助?我希望有某种方式,说“当所有 HttpContext 都消失了,意思是,当没有更多的请求被处理时,请关闭”?
      • 我不需要等待所有请求。我的网站是在控制台应用程序中启动的本地网站。因此,当用户按下 CTRL+C 时,我想立即将其关闭。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-23
      相关资源
      最近更新 更多