0

I'm attempting to work with the Console.ReadKey() function in order to intercept the user's keystrokes and rebuild what they are typing on the screen (as I'll need to clear the screen often, move the cursor often, and this seemed like the most full-proof method of making sure what they typed didn't vanish or appear at random points all over the screen.

My question is: Has anyone else ever experienced a 1 character "lag", for lack of a better term, when doing something similar? Say I want to type the word "This". When I press "T", nothing shows up, no matter how long I wait. When I press "h", the "T" appears. "i", the "h" appears. The letter I type will not appear until I hit another key, even if that key is the space bar. Does anyone have any suggestions for what I am doing wrong? I'm sure it has to do with how I am using Console.Readkey, I just don't see what alternative would work. I have attached a small and simple example of this below.

Thank you!

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;

    namespace ConsoleApplication2

{
    class Program
    {

        private static string userInput = "";
        static ConsoleKeyInfo inf;
        static StringBuilder input = new StringBuilder();

        static void Main(string[] args)
        {
            Thread tickThread = new Thread(new ThreadStart(DrawScreen));
            Thread userThread = new Thread(new ThreadStart(UserEventHandler));
            tickThread.Start();
            Thread.Sleep(1);
            userThread.Start();
            Thread.Sleep(20000);
            tickThread.Abort();
            userThread.Abort();
        }


        private static void DrawScreen()
        {
            while (true)
            {
                Console.Clear();
                Console.SetCursorPosition(0, 0);
                Console.Write("> " + userInput);
                Thread.Sleep(300);
            }
        }


        private static void UserEventHandler()
        {
            inf = Console.ReadKey(true);

            while (true)
            {
                if (inf.Key != ConsoleKey.Enter)
                    input.Append(inf.KeyChar);
                else
                {
                    input = new StringBuilder();
                    userInput = "";
                }

                inf = Console.ReadKey(true);

                userInput = input.ToString();

            }
        }

    }
}
C Smith
  • 778
  • 2
  • 14
  • 31
  • My apologies- I copied just this bit out of my main program to have a simplistic example. It serves a purpose is my main program, it serves none here. I will remove it from this example. – C Smith Jul 25 '12 at 05:53
  • Perhaps see [`KeyAvailable`](http://msdn.microsoft.com/en-us/library/system.console.keyavailable.aspx) .. might be able to eliminate the threading entirely? –  Jul 25 '12 at 05:53
  • 1
    This is a mess. Please clarify. What are you trying to do? Why can't you use readline, and get everything the type up until the hit enter? – GrayFox374 Jul 25 '12 at 05:54
  • In my main program, which is just a crappy little game I am using to learn C#, I want the console split into 2 sections: All of the top and middle of the screen will be a map/hud/whatever for the player. It will constantly be refreshing. This will mean that every 1.5 seconds or so, I will either be clearing the screen OR using Console.SetCursorPosition to move the cursor to different parts of the screen. The bottom of the screen is reserved for what the user types. That setup, however, will constantly clear what the user is typing or risk their characters going all over the screen. – C Smith Jul 25 '12 at 05:56
  • 1
    I asked a question about that yesterday, and was told my best bet was to "rebuild the user's input using Console.ReadKey". Thus this little bit of what I'm doing. This example just focuses on that goal. http://stackoverflow.com/questions/11628432/c-sharp-allow-simultaneous-console-input-and-output – C Smith Jul 25 '12 at 05:57
  • pst- I'll give that a try! :) Thanks for the response – C Smith Jul 25 '12 at 06:04

1 Answers1

5

It is because you have 2 times Console.ReadKey()

If you change your code into this

    private static void UserEventHandler()
    {
        while (true)
        {
            inf = Console.ReadKey(true);
            if (inf.Key != ConsoleKey.Enter)
                input.Append(inf.KeyChar);
            else
            {
                input = new StringBuilder();
                userInput = "";
            }
            userInput = input.ToString();
        }
    }

It does not lag. the second Console.ReadKey() is blocking in your code. I did not check if you need the parameter true to the readkey, that's for you to find out

bart s
  • 5,068
  • 1
  • 34
  • 55