using System; using NLog; using NzbDrone.Core.Lifecycle; namespace Radarr.Host { public interface ICancelHandler { void Attach(); } public class CancelHandler : ICancelHandler { private readonly ILifecycleService _lifecycleService; private object _syncRoot; private volatile bool _cancelInitiated; public CancelHandler(ILifecycleService lifecycleService) { _lifecycleService = lifecycleService; } public void Attach() { Console.CancelKeyPress += HandlerCancelKeyPress; _syncRoot = new object(); } private void HandlerCancelKeyPress(object sender, ConsoleCancelEventArgs e) { // Tell system to ignore the Ctrl+C and not terminate. We'll do that. e.Cancel = true; var shouldTerminate = false; lock (_syncRoot) { shouldTerminate = _cancelInitiated; _cancelInitiated = true; } // TODO: Probably should schedule these on the threadpool. if (shouldTerminate) { UngracefulShutdown(); } else { GracefulShutdown(); } } private void GracefulShutdown() { Console.WriteLine("Shutdown requested, press Ctrl+C again to terminate directly."); // TODO: Sent ApplicationShutdownRequested event or something like it. _lifecycleService.Shutdown(); } private void UngracefulShutdown() { Console.WriteLine("Termination requested."); // TODO: Kill it. Shutdown NLog and invoke Environment.Exit. LogManager.Configuration = null; Environment.Exit(0); } } }