问题
I need to notify systemd
that my service has started up successfully, and a task it needs to run after startup requires that the server is already listening on the target Unix domain socket.
I am using IWebHost::Run
to start the server, and that is a blocking call. Additionally, I am unable to find any obvious way to set a delegate or callback event for successful initialization.
Anyone?
回答1:
On
.Net Core 1.x
it is safe to just runIWebHost.Start()
and assume that the server is initialized afterwards (instead ofRun()
that blocks the thread). Check the source.var host = new WebHostBuilder() .UseKestrel() (...) .Build(); host.Start();
If you are using
.NET Core 2.0 Preview 1
(or later), the source is different, the synchronous method is not available anymore so you should awaitIWebHost.StartAsync()
and assume everything is ready afterwards.
回答2:
You may use 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; }
Look into this SO post for the configuration example.
回答3:
This is what I ended up going with, for now. Seems to be working fine:
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...");
Then, in the Ctrl+C event handler:
private static void OnConsoleCancelKeyPress(object sender, ConsoleCancelEventArgs e)
{
Log.Debug("Got Ctrl+C from console.");
CancelTokenSource.Cancel();
}
回答4:
This is what I did to overcome the issue.
1- I registered ApplicationStopped
event. So that it brute force terminates the app by calling Kill()
method of the current process.
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- Don't forget to use the UseConsoleLifetime()
while building the host.
Host.CreateDefaultBuilder(args).UseConsoleLifetime(opts => opts.SuppressStatusMessages = true);
See useconsolelifetime docs
来源:https://stackoverflow.com/questions/44662711/how-can-i-know-when-kestrel-has-started-listening