Console.CancelKeyPressのバグ
.Net Frameworkのコンソールアプリケーションでは、Console.CancelKeyPressイベントにハンドラを登録することでCtrl+Cが押された時の動作をハンドルできる。
そのままプログラムを終了させたくない場合はConsoleCancelEventArgs.Cancel
にtrue
を設定する。
ConsoleCancelEventHandler handler = (s, e) => { Console.WriteLine("Cancelled!"); e.Cancel = true; }; Console.CancelKeyPress += handler;
特定の画面だけハンドルしたかったのでハンドラを削除すると、再登録した時に何故か反応しない。
ConsoleCancelEventHandler handler = (s, e) => { Console.WriteLine("Cancelled!"); e.Cancel = true; }; Console.CancelKeyPress += handler; // OK Console.CancelKeyPress -= handler; Console.CancelKeyPress += handler; // NG
調べてみると、.Net Frameworkのバグのようだ。(4.5.2で確認)
CancelKeyPressから最後のハンドラが削除されるとWindowsに登録されたコールバックが削除されてしまうらしい。
最後のハンドラが削除されないようにダミーを登録しておくことで回避できる。
Console.CancelKeyPress += delegate { }; ConsoleCancelEventHandler handler = (s, e) => { Console.WriteLine("Cancelled!"); e.Cancel = true; }; Console.CancelKeyPress += handler; // OK Console.CancelKeyPress -= handler; Console.CancelKeyPress += handler; // OK