0

I'm working on a c# console application.

I have to show a timer on screen at a specified cursor location and at the same time a user shall input something.

How can I do this?

Console.SetCursorPosition(x, y);
//timer code here
Console.SetCursorPosition(x, y); // cursor goes to some other location because timer is displayed at top-right of the screen.

My problem is that this method isn't synchronized. I have to wait until the cursor go to that location then display time and comes back so that I can type.

enter image description here

John Saunders
  • 160,644
  • 26
  • 247
  • 397
  • You say you are working on a console application, but you've tagged it with [tag:ASP.NET]. Explain? – JDB Oct 09 '13 at 18:36
  • `My problem is that this method isn't synchronized` what do you mean by that? – tnw Oct 09 '13 at 18:37
  • Can you post some more code? For example where user input taken. Also posting the actual values of x and y will help too. – bytefire Oct 09 '13 at 18:43
  • I'll try my best to explain. I added a timer in my console application. Here a pic how it looks. http://i.imgur.com/Ckl9ADG.png I'm using Console.SetCursorPosition to display the timer (Updates every second). Then after that, i switch back to the area where the user is inputting the answer. Are you getting it now? – Raghav Sharma Oct 09 '13 at 18:48
  • 1
    I see what you mean. Have a look at this: http://stackoverflow.com/questions/5772203/how-to-reserve-a-row-for-input-in-multi-threaded-console. From that link it doesn't seem like a straightforward task. – bytefire Oct 09 '13 at 18:50

2 Answers2

0

You can use a Timer even while reading a line. See the code below for a working example:

class Program
{
    private static System.Timers.Timer _timer;

    static void Main( string[] args )
    {

        _timer = new System.Timers.Timer( 1000 );
        _timer.Elapsed += Timer_Elapsed;
        _timer.AutoReset = true;
        _timer.Start();

        Console.CursorLeft = 0;
        Console.CursorTop = 5;
        // Type something here...
        var l_readline = Console.ReadLine();
        // Print it out... (to show it correctly reads the input)
        Console.WriteLine( l_readline );
        Console.ReadKey( true );
    }

    private static void Timer_Elapsed( object sender, System.Timers.ElapsedEventArgs e )
    {
        int l_left = Console.CursorLeft;
        int l_top = Console.CursorTop;

        Console.CursorLeft = 0;
        Console.CursorTop = 0;
        Console.Write( DateTime.Now.ToLongTimeString() );
        Console.CursorLeft = l_left;
        Console.CursorTop = l_top;
    }

}

As long as you reset the cursor position back to it's original position after you are finished, I do not think you will have much trouble with most forms of input.

JDB
  • 25,172
  • 5
  • 72
  • 123
  • That's a [Cyberman](https://www.google.com/search?q=cyberman&es_sm=122&source=lnms&tbm=isch&sa=X&ei=P6hVUvqNKu66yAHN1ICQDw&ved=0CAkQ_AUoAQ&biw=1440&bih=775&dpr=1) from Dr. Who! – Idle_Mind Oct 09 '13 at 19:03
  • Thank you, kind sir. Wish i could rep you but can't. – Raghav Sharma Oct 11 '13 at 09:18
0

The simplest way to handle something like this would be to store the current Cursor(X, Y), write the time to your Time(X, Y), then set the cursor back to Cursor(X, Y).

private const int TIME_LEFT = 40;
private const int TIME_RIGHT = 2;

private void WriteTime() {
  var left = Console.CursorLeft;
  var right = Console.CursorTop;
  try {
    Console.SetCursorPosition(TIME_LEFT, TIME_RIGHT);
    Console.Write(DateTime.Now);
  } finally {
    Console.SetCursorPosition(left, right);
  }
}

Not knowing what else you are doing, that's the best suggestion I have for you.

This should occur faster than humans can react to.