Search code examples
c#inputconsole

c# reading user input without stopping an app



I know I can use ReadKey for that but it will freeze the app until user presses a key. Is it possible (in console app) to have some loop running and still be able to react? I can only think of events but not sure how to use them in console. My idea was that the loop would check for input during each iteration.


Solution

  • They way I have done this for my own application was to have a dedicated thread that calls into System.Console.ReadKey(true) and puts the keys pressed (and any other events) into a message queue.

    The main thread then services this queue in a loop (in a similar fashion to the main loop in a Win32 application), ensuring that rendering and event processing is all handled on a single thread.

    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)
        }
    }