Permalink
Cannot retrieve contributors at this time
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
115 lines (95 sloc)
4.7 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright (c) .NET Foundation. All rights reserved. | |
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | |
using System; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using Microsoft.Extensions.Logging; | |
using Microsoft.Extensions.Logging.Abstractions; | |
using Microsoft.Extensions.Options; | |
namespace Microsoft.Extensions.Hosting.Internal | |
{ | |
/// <summary> | |
/// Listens for Ctrl+C or SIGTERM and initiates shutdown. | |
/// </summary> | |
public class ConsoleLifetime : IHostLifetime, IDisposable | |
{ | |
private readonly ManualResetEvent _shutdownBlock = new ManualResetEvent(false); | |
private CancellationTokenRegistration _applicationStartedRegistration; | |
private CancellationTokenRegistration _applicationStoppingRegistration; | |
public ConsoleLifetime(IOptions<ConsoleLifetimeOptions> options, IHostEnvironment environment, IHostApplicationLifetime applicationLifetime, IOptions<HostOptions> hostOptions) | |
: this(options, environment, applicationLifetime, hostOptions, NullLoggerFactory.Instance) { } | |
public ConsoleLifetime(IOptions<ConsoleLifetimeOptions> options, IHostEnvironment environment, IHostApplicationLifetime applicationLifetime, IOptions<HostOptions> hostOptions, ILoggerFactory loggerFactory) | |
{ | |
Options = options?.Value ?? throw new ArgumentNullException(nameof(options)); | |
Environment = environment ?? throw new ArgumentNullException(nameof(environment)); | |
ApplicationLifetime = applicationLifetime ?? throw new ArgumentNullException(nameof(applicationLifetime)); | |
HostOptions = hostOptions?.Value ?? throw new ArgumentNullException(nameof(hostOptions)); | |
Logger = loggerFactory.CreateLogger("Microsoft.Hosting.Lifetime"); | |
} | |
private ConsoleLifetimeOptions Options { get; } | |
private IHostEnvironment Environment { get; } | |
private IHostApplicationLifetime ApplicationLifetime { get; } | |
private HostOptions HostOptions { get; } | |
private ILogger Logger { get; } | |
public Task WaitForStartAsync(CancellationToken cancellationToken) | |
{ | |
if (!Options.SuppressStatusMessages) | |
{ | |
_applicationStartedRegistration = ApplicationLifetime.ApplicationStarted.Register(state => | |
{ | |
((ConsoleLifetime)state).OnApplicationStarted(); | |
}, | |
this); | |
_applicationStoppingRegistration = ApplicationLifetime.ApplicationStopping.Register(state => | |
{ | |
((ConsoleLifetime)state).OnApplicationStopping(); | |
}, | |
this); | |
} | |
AppDomain.CurrentDomain.ProcessExit += OnProcessExit; | |
Console.CancelKeyPress += OnCancelKeyPress; | |
// Console applications start immediately. | |
return Task.CompletedTask; | |
} | |
private void OnApplicationStarted() | |
{ | |
Logger.LogInformation("Application started. Press Ctrl+C to shut down."); | |
Logger.LogInformation("Hosting environment: {envName}", Environment.EnvironmentName); | |
Logger.LogInformation("Content root path: {contentRoot}", Environment.ContentRootPath); | |
} | |
private void OnApplicationStopping() | |
{ | |
Logger.LogInformation("Application is shutting down..."); | |
} | |
private void OnProcessExit(object sender, EventArgs e) | |
{ | |
ApplicationLifetime.StopApplication(); | |
if(!_shutdownBlock.WaitOne(HostOptions.ShutdownTimeout)) | |
{ | |
Logger.LogInformation("Waiting for the host to be disposed. Ensure all 'IHost' instances are wrapped in 'using' blocks."); | |
} | |
_shutdownBlock.WaitOne(); | |
// On Linux if the shutdown is triggered by SIGTERM then that's signaled with the 143 exit code. | |
// Suppress that since we shut down gracefully. https://github.com/aspnet/AspNetCore/issues/6526 | |
System.Environment.ExitCode = 0; | |
} | |
private void OnCancelKeyPress(object sender, ConsoleCancelEventArgs e) | |
{ | |
e.Cancel = true; | |
ApplicationLifetime.StopApplication(); | |
} | |
public Task StopAsync(CancellationToken cancellationToken) | |
{ | |
// There's nothing to do here | |
return Task.CompletedTask; | |
} | |
public void Dispose() | |
{ | |
_shutdownBlock.Set(); | |
AppDomain.CurrentDomain.ProcessExit -= OnProcessExit; | |
Console.CancelKeyPress -= OnCancelKeyPress; | |
_applicationStartedRegistration.Dispose(); | |
_applicationStoppingRegistration.Dispose(); | |
} | |
} | |
} |