protected override void RunProxyImpl(CommandSettings settings) { // argument checks Debug.Assert(settings != null); using (ControllerThreadSynchronizer synchronizer = new ControllerThreadSynchronizer()) { // prepare Ctrl+C handler ConsoleCancelEventHandler onCtrlC = (o, e) => { e.Cancel = true; AwakeControllerThread(ControllerThreadSynchronizer.EventKind.Quit); }; // connect Ctrl+C handler Console.CancelKeyPress += onCtrlC; try { ControllerThreadSynchronizer.EventKind eventKind = ControllerThreadSynchronizer.EventKind.None; do { Debug.Assert(eventKind == ControllerThreadSynchronizer.EventKind.None || eventKind == ControllerThreadSynchronizer.EventKind.Resume); // run the proxy bool completed = false; using (RunningProxyState runningProxyState = StartProxy(settings, saveCredentials: true, checkPreviousBackup: false)) { // log & message LogProxyStarted(eventKind == ControllerThreadSynchronizer.EventKind.Resume); Console.WriteLine(Resources.CLICommandBase_Message_StartListening); Console.WriteLine(Resources.CLICommandBase_Message_StartingNote); // wait for Ctrl+C or other events RegisterControllerThreadSynchronizer(synchronizer); eventKind = synchronizer.WaitForEvent(); // stop the proxy completed = runningProxyState.Stop(eventKind == ControllerThreadSynchronizer.EventKind.SystemSessionEnding, 5000); } LogProxyStopped(completed, eventKind == ControllerThreadSynchronizer.EventKind.Suspend); Console.WriteLine(completed ? Resources.CLICommandBase_Message_Completed : Resources.CLICommandBase_Message_NotCompleted); // resume the thread which originally accepts the event synchronizer.NotifyEventHandledAndWaitForAcknowledgment(); // decide the next step while (eventKind == ControllerThreadSynchronizer.EventKind.Suspend) { // wait for the next event RegisterControllerThreadSynchronizer(synchronizer); eventKind = synchronizer.WaitForEvent(); synchronizer.NotifyEventHandledAndWaitForAcknowledgment(); } if (eventKind != ControllerThreadSynchronizer.EventKind.Resume) { // quit Debug.Assert(eventKind == ControllerThreadSynchronizer.EventKind.Quit || eventKind == ControllerThreadSynchronizer.EventKind.SystemSessionEnding); break; } } while (true); } finally { // disconnect Ctrl+C handler Console.CancelKeyPress -= onCtrlC; } } return; }