Как использовать консоль.CancelKeyPress in.NET 4? (Работает отлично in.NET 3.5 и ниже)

Я пишу консольное приложение на C# 4 и хочу изящно отменить свою программу, и Ctrl + C нажата. Следующий код, который я использовал много раз раньше, но теперь при попытке использовать его в .NET 4, кажется странным необработанным исключением.

namespace ConsoleTest
{
    class Program
    {
        private static bool stop = false;

        static void Main(string[] args)
        {
            System.Console.TreatControlCAsInput = false;
            System.Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);

            while (!stop)
            {
                System.Console.WriteLine("waiting...");
                System.Threading.Thread.Sleep(1000);
            }
            System.Console.WriteLine("Press any key to exit...");
            System.Console.ReadKey(true);
        }

        static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
        {
            stop = true;
            e.Cancel = true;
        }
    }
}

если я изменю целевую платформу на .NET 3.5, она будет работать.

EDIT: кажется, этот человек видит то же вопрос: http://johnwheatley.wordpress.com/2010/04/14/net-4-control-c-event-handler-broken/

2 ответов


Это известная проблема на Microsoft Connect.

обратите внимание, что он работает вне отладчика.


для консольного приложения под VS2010 и .NET 4.0 я использую следующий (не очень чистый) обходной путь:

  1. в свойствах проекта, в разделе [отладка], установите флажок [включить отладку неуправляемого кода];
  2. во время запуска кода класса программы вставьте следующее (Это .NET 2 style, используйте lambdas на свое усмотрение):

Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
{
  if (e.SpecialKey == ConsoleSpecialKey.ControlC)
  {
    e.Cancel = true; // tell the CLR to keep running
  }
  else if (e.SpecialKey == ConsoleSpecialKey.ControlBreak)
  {
    //e.Cancel = true; // "Applications are not allowed to cancel the ....
  }
  // do whatever you must to inform threads on application exit, etc
}

хотя это и не очевидно, этот код позволит вам отлаживать обработчик CTRL-C, например Итак:

  1. запустите программу под отладчиком (F5);
  2. убедитесь, что консоль вашей программы имеет фокус;
  3. нажмите ctrl + pause (на моей широте e6500 мне нужно удерживать ctrl и Fn и F12);

отладчик спросит вас об этом прерывании, нажмите [игнорировать] , и вы окажетесь в обработчике (убедитесь, что была установлена точка останова)

тот же код будет выполняться, если ctrl+c нажата, единственное отличие-Вы должны установить e.Отменить на true.

как указывали все остальные, проблема не существует во время выполнения, это обходное решение предназначено только для перехода через обработчик.