2012-01-09 3 views
3

Есть ли способ обнаружить как Readline, так и ReadKey, так что в большинстве случаев он ведет себя как чтение, за исключением некоторых специальных входных ключей, которые должны быть обнаружены?Использование Readline() и ReadKey() Одновременно

Мне нужна некоторая «параллельная» реализация, чтобы ввести одновременность. ниже код является синхронным и не отвечает моя потребность

while ((line = Console.ReadLine()) != "x") 
{  
    if (line == "BLABLA") 
    { 
     //Stuff 
    } 

    else 
    { 
     //Stuff 
    } 

    ConsoleKeyInfo ki = Console.ReadKey(true); 
    if ((ki.Key == ConsoleKey.V) && (ki.Modifiers == ConsoleModifiers.Control)) 
    { 
     //Stuff 
    } 
} 
+0

возможно дубликат http://stackoverflow.com/questions/5891538/c-sharp-listen-for-key-press-in-console-app – Alex

ответ

1

Нет, не как таковой. Оба метода блокируются до тех пор, пока пользователь ничего не введет на консоль. Таким образом, даже если вы найдете способ, чтобы оба они выполнялись параллельно, он не будет детерминированным, чтобы получить первый снимок.

Существует (не очевидная) аналогичная проблема: как сделать Console.ReadLine() прерывание/перерыв через определенное количество времени без ввода пользователем.

Там было несколько попыток для этой проблемы здесь:

Большинство моделируются вокруг либо создать свою собственную версию ReadLine функцию, которая добавляет тайм-аут (или в вашем случае специальная обработка для определенного символа (коды)) или использование какой-либо резьбы.

Оба способа являются либо нетривиальными, либо имеют свои собственные проблемы (убедитесь, что вы просматриваете комментарии, даже для принятых ответов).

Вкратце, я думаю, вам нужно будет перевернуть свою собственную версию ReadLine, основанной на Console.ReadKey, с вашей специальной обработкой и большей частью подлинного поведения Console.ReadLine, которое вам нужно. Обратите внимание, что это даже включает в себя такие основные вещи, как RETURN, ВИДЕ СТРЕЛОК, обработка BACKSPACE и т.д.

Update: Существует getline.cs кода из Mono project, который реализует возможность редактирования в линии, как это было предусмотрено каким-то почтенным UNIX shell (режим EMACS, если вам интересно). Для этого я считаю, что ему потребуется реализовать какую-то замену ReadLine, хотя я не проверял. Возможно, вы можете использовать это как отправную точку.

+0

Определенно не стоит того, чтобы реализовать всю комплексную логику Readline. Слишком много хлопот за такую ​​«маленькую» особенность. Не могу поверить, что это невозможно более просто, так как это функция, которую можно было бы ожидать от оболочки. Кроме того, я действительно не понял: что отменяет readline после определенного количества времени на мой пост? –

+0

@MikaJacobi Это также требует, чтобы вы адаптировали ReadLine так, как изначально не было. В частности, по крайней мере, некоторые реализации также требуют перезаписи, которые вы можете расширить своей функциональностью. –

1

Вот функция, которую я только что сделал для этого.

В настоящее время он обрабатывает только обратное пространство, вводит и Esc, но его можно легко модифицировать для обработки других ключей, если вы сочтете это необходимым.

// returns null if user pressed Escape, or the contents of the line if they pressed Enter. 
    private static string ReadLineOrEsc() 
    { 
     string retString = ""; 

     int curIndex = 0; 
     do 
     { 
      ConsoleKeyInfo readKeyResult = Console.ReadKey(true); 

      // handle Esc 
      if (readKeyResult.Key == ConsoleKey.Escape) 
      { 
       Console.WriteLine(); 
       return null; 
      } 

      // handle Enter 
      if (readKeyResult.Key == ConsoleKey.Enter) 
      { 
       Console.WriteLine(); 
       return retString; 
      } 

      // handle backspace 
      if (readKeyResult.Key == ConsoleKey.Backspace) 
      { 
       if (curIndex > 0) 
       { 
        retString = retString.Remove(retString.Length - 1); 
        Console.Write(readKeyResult.KeyChar); 
        Console.Write(' '); 
        Console.Write(readKeyResult.KeyChar); 
        curIndex--; 
       } 
      } 
      else 
      // handle all other keypresses 
      { 
       retString += readKeyResult.KeyChar; 
       Console.Write(readKeyResult.KeyChar); 
       curIndex++; 
      } 
     } 
     while (true); 
    }