То, как я сделал это для своего собственного приложения, заключалось в том, чтобы иметь выделенный поток, который вызывает System.Console.ReadKey(true)
и помещает нажатые клавиши (и любые другие события) в очередь сообщений.
Основной потокзатем обслуживает эту очередь в цикле (аналогично основному циклу в приложении Win32), обеспечивая обработку и обработку событий в одном потоке.
private void StartKeyboardListener()
{
var thread = new Thread(() => {
while (!this.stopping)
{
ConsoleKeyInfo key = System.Console.ReadKey(true);
this.messageQueue.Enqueue(new KeyboardMessage(key));
}
});
thread.IsBackground = true;
thread.Start();
}
private void MessageLoop()
{
while (!this.stopping)
{
Message message = this.messageQueue.Dequeue(DEQUEUE_TIMEOUT);
if (message != null)
{
switch (message.MessageType)
{
case MessageType.Keyboard:
HandleKeyboardMessage((KeyboardMessage) message);
break;
...
}
}
Thread.Yield(); // or Thread.Sleep(0)
}
}