【问题标题】:How can I know when Kestrel has started listening?我怎么知道 Kestrel 何时开始收听?
【发布时间】:2017-11-23 13:37:14
【问题描述】:

我需要通知systemd 我的服务已成功启动,并且它需要在启动后运行的任务要求服务器已在目标 Unix 域套接字上侦听。 p>

我正在使用IWebHost::Run 启动服务器,这是一个阻塞调用。此外,我找不到任何明显的方法来设置成功初始化的委托或回调事件。

有人吗?

【问题讨论】:

    标签: c# asp.net-core kestrel


    【解决方案1】:

    这就是我现在最终要做的。似乎工作正常:

    host.Start();
    
    Log.Information("Press Ctrl+C to shut down...");
    Console.CancelKeyPress += OnConsoleCancelKeyPress;
    
    var waitHandles = new WaitHandle[] {
        CancelTokenSource.Token.WaitHandle
    };
    
    WaitHandle.WaitAll(waitHandles);
    Log.Information("Shutting down...");
    

    然后,在 Ctrl+C 事件处理程序中:

    private static void OnConsoleCancelKeyPress(object sender, ConsoleCancelEventArgs e)
    {
        Log.Debug("Got Ctrl+C from console.");
        CancelTokenSource.Cancel();
    }
    

    【讨论】:

    • 这段代码如何帮助您检测 Kestrel 何时完成初始化?
    • 您不是说除非我使用的是 2.0 预览版 1,否则在 Start() 调用之后假设 Kestrel 已准备就绪是安全的吗?不应该有关于它是异步的评论。
    • 我问是因为我不知道,你的回答我也不清楚。我以为你在破解 Cancel 事件来检测初始化的结束。然后研究了一下,发现 Start 是安全的,所以我发布了它,并假设你的代码奇迹般地工作,如果有的话。现在我相信您编写了如何正确阻止当前线程的代码。在您的回答中添加一些措辞可以避免所有的误解。
    【解决方案2】:
    • .Net Core 1.x 上运行IWebHost.Start() 并假设服务器随后被初始化是安全的(而不是阻止线程的Run())。检查source

      var host = new WebHostBuilder()
          .UseKestrel()
          (...)
          .Build();
      
      host.Start();
      
    • 如果您使用.NET Core 2.0 Preview 1(或更高版本)、source is different,则同步方法不再可用,因此您应该等待IWebHost.StartAsync() 并假设之后一切就绪。

      李>

    【讨论】:

    • 这就是我最终做的;关于 Start() 异步的评论是错误的。
    【解决方案3】:

    您可以使用Microsoft.AspNetCore.Hosting.IApplicationLifetime:

    /// <summary>
    /// Triggered when the application host has fully started and is about to wait
    /// for a graceful shutdown.
    /// </summary>
    CancellationToken ApplicationStarted { get; }
    

    查看此SO post 以获取配置示例。

    【讨论】:

      【解决方案4】:

      这就是我为解决这个问题所做的。

      1- 我注册了ApplicationStopped 事件。这样它就会通过调用当前进程的Kill()方法来暴力终止应用程序。

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

      See IHostApplicationLifetime docs


      2- 在构建主机时不要忘记使用UseConsoleLifetime()

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

      See useconsolelifetime docs

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-02-05
        • 2011-06-04
        • 2019-06-11
        • 1970-01-01
        • 1970-01-01
        • 2015-06-19
        • 1970-01-01
        相关资源
        最近更新 更多