1

the clock will automatically run myclock.Tick and display on the console. and i would like to reset the clock when i press spacebar.

however, it seems i can't end the loop when i press the spacebar.

So, how can i reset the clock by keyinput?

it is because of the console.readkey

Correct Program.cs:

public static void Main(string[] args)
    {
        Clock myclock = new Clock();
        while (true)
        {
            Console.WriteLine("Press 'spacebar' to view the time and 'r' to reset the time");
            if (Console.ReadKey().Key == ConsoleKey.Spacebar)
            {
                for (int i = 0; i < 86400;i++)
                {
                    myclock.displayTime();
                    Thread.Sleep(1000);
                    myclock.Update();

                    if  (Console.KeyAvailable)
                    {
                        ConsoleKeyInfo cki = Console.ReadKey(true);
                        if (cki.Key == ConsoleKey.R)
                        {
                            myclock.ClockReset();
                            Console.WriteLine("\nClock has been reset");
                            break;
                        }
                    }
                }
            }            
    }
Leo Chong
  • 11
  • 2

3 Answers3

1

Try using Console.KeyAvailable like shown in the example below. In your case handle the exit inside if statement :

 while( true )
    {
      if( Console.KeyAvailable ) // since .NET 2.0
      {
        char c = Console.ReadKey().KeyChar ;
        Console.Write( c );
      }
    }
1

Maybe some addition for your understanding:

The problem is that your inner for-loop blocks the do-while-loop. The condition of the do-while isn't checked until the for-loop has finished.

Try to use a method to check the key input inside your clock-incrementing loop.

Edit: I can't say if the simple check against a key press, as stated in other answers, would help. I guess that this would need the program to detect the key press just in the moment the for-loop is processed. When you don't press the spacebar at least one second, the chances are low that this would work.

A suitable soution could be to put the increment of the clock into another thread/task which isn't blocking your input thread.

Edit 2: Also you should be aware that the displayed time is delayed by one second in your example because you increment the time value first, then wait for a second and only then display the incremented time. If you're doing it this way, you should consider doing it like this:

myclock.Tick();
myclock.displayTime();

// Increment and display first, then put thread to sleep
Thread.Sleep(1000);

Or, if you want to start with zero:

myclock.displayTime();

Thread.Sleep(1000);
myclock.Tick();
Niklas
  • 102
  • 10
  • Thank you for your advice. I think this is the problem as it is blocking my input. Could you give me some example? – Leo Chong May 11 '18 at 11:41
  • Try the approach posted by @chris-aby-antony to check against the key press in your for-loop and `break` the loop if the condition is fulfilled. But as I said, this requires you to hold the spacebar for one second in the worst case. – Niklas May 11 '18 at 11:44
  • it does require me to hold the spacebar.....if i release the spacebar it won't implement.... – Leo Chong May 11 '18 at 12:25
  • Yep - that's because of your outer if. Remove that and its no longer required to hold the spacebar. You also might consider setting i back to zero when resetting your clock. – Niklas May 11 '18 at 13:03
0

You will need to listen to a key-press event and then handle that like setting a flag for the loop to check against.

Taken from: Trying to detect keypress

private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
    if (e.KeyCode == Keys.F1 && e.Alt)
    {
        //do something
    }
}
Threezool
  • 453
  • 4
  • 11