Консоль.Сбой доступа к ключу при запуске процесса

#c# #.net #console-application #system.diagnostics

#c# #.net #консольное приложение #system.diagnostics

Вопрос:

Вот фрагмент кода, который работает просто отлично. Поскольку я имитирую длительный процесс, любые нажатия клавиш ставятся в очередь. Console.Available Возвращает true и false так, как указано в документации, это должно быть. Здесь все работает отлично:

 while (true) {
   Console.WriteLine("Starting long task...");
   // Simulate some long task by sleeping 3 seconds
   System.Threading.Thread.Sleep(3000);
   Console.WriteLine("Long task is finished.");

   if (Console.KeyAvailable) 
      Console.WriteLine("A key is available: "   Console.ReadKey(false).Key);
   else
      Console.WriteLine("*** No Key available ***");
}
  

Вот проблема: когда я заменяю Thread.Sleep() кодом для создания и запуска реального Process , Console.KeyAvailable перестает работать. Console.KeyAvailable ведет себя неустойчиво, обычно возвращаясь false , но иногда возвращается true , если я набираю достаточно ключей достаточно быстро.

У кого-нибудь есть объяснение этому?

 while (true) {
   LongRunningProcess("someFile.bin");

   if (Console.KeyAvailable) 
      Console.WriteLine("A key is available: "   Console.ReadKey(false).Key);
   else
      Console.WriteLine("*** No Key available ***");
}

private static bool LongRunningProcess(String filename) {
   ProcessStartInfo processStartInfo = new ProcessStartInfo("BlahBlahBlah.exe", filename);
   processStartInfo.UseShellExecute = false;
   processStartInfo.RedirectStandardError = true;

   Process p = new Process();
   p.StartInfo = processStartInfo;
   p.Start();

   StreamReader stdError = p.StandardError;

   int readResult = stdError.Read();

   p.Close();

   if (readResult != -1) // error was written to std error
      return false;

   return true;
} 
  

Ответ №1:

Запущенный процесс показывает окно, которое становится активным окном. Ваше консольное приложение получает ввод с клавиатуры только в то время, когда окно вашей консоли является активным. Попробуйте присвоить CreateNoWindow свойству ProcessStartInfo значение true.