Как использовать Console.CancelKeyPress в .NET 4? (Отлично работает в .NET 3.5 и ниже) - PullRequest
10 голосов
/ 19 мая 2010

Я пишу консольное приложение на 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;
        }
    }
}

Если я изменю Target Framework на .NET 3.5, он будет работать.

РЕДАКТИРОВАТЬ: Кажется, этот человек видит ту же проблему: http://johnwheatley.wordpress.com/2010/04/14/net-4-control-c-event-handler-broken/

Ответы [ 2 ]

13 голосов
/ 19 мая 2010

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

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

2 голосов
/ 21 августа 2013

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

  1. в свойствах проекта в разделе [Отладка] установите флажок [Включить отладку неуправляемого кода];
  2. во время кода запуска вашего класса Program вставьте следующее (это стиль .NET 2, используйте 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 + пауза (на моей широте e6500, мне нужно удерживать Ctrl и Fn и F12);

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

ЖЕ код будет выполняться, если нажаты ctrl + c, единственное отличие - вы должны установить для e.Cancel значение true.

Как отмечают все остальные, проблема НЕ существует во время выполнения, этот обходной путь предназначен ТОЛЬКО для пошагового выполнения обработчика.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...