4444
4444

Reputation: 3680

Wait for Keypress (or) N Seconds to Expire

Suppose my console program performs multiple lengthy tasks. Between these tasks, I'd like it to pause - either for a few seconds or until any key gets pressed. (Whichever comes first.)

These criteria are easy to check on their own, but they refuse to get along when I try combining them: Either the timing mechanism pauses for a few seconds before ReadKey starts, or Readkey blocks out the thread entirely until satisfied. How can I satisfy both conditions?

Upvotes: 8

Views: 12668

Answers (5)

Matt Vukomanovic
Matt Vukomanovic

Reputation: 1440

Extending from ikh's answer I wanted a count down with mine

        var original = DateTime.Now;
        var newTime = original;

        var waitTime = 10;
        var remainingWaitTime = waitTime;
        var lastWaitTime = waitTime.ToString();
        var keyRead = false;
        Console.Write("Waiting for key press or expiring in " + waitTime);
        do
        {
            keyRead = Console.KeyAvailable;
            if (!keyRead)
            {
                newTime = DateTime.Now;
                remainingWaitTime = waitTime - (int) (newTime - original).TotalSeconds;
                var newWaitTime = remainingWaitTime.ToString();
                if (newWaitTime != lastWaitTime)
                {
                    var backSpaces = new string('\b', lastWaitTime.Length);
                    var spaces = new string(' ', lastWaitTime.Length);
                    Console.Write(backSpaces + spaces + backSpaces);
                    lastWaitTime = newWaitTime;
                    Console.Write(lastWaitTime);
                    Thread.Sleep(25);
                }
            }
        } while (remainingWaitTime > 0 && !keyRead);

Upvotes: 2

CodeDemen
CodeDemen

Reputation: 1971

Something like this?

bool IsPaused;
bool IsKeyPaused;

void Pause(){}
void UnPause(){}

void KeyDown(){
    if(!IsPaused)
    {
        IsPaused = true;
        IsKeyPaused = true;
        Pause();
    }
}
void KeyUp(){
    if(IsKeyPaused)
    {
        IsPaused = false;
        IsKeyPaused = false;
        UnPause();
    }
}
void TimerPause(){
    if(!IsPaused)
    {
        IsPaused = true;
        Pause();
    }
}
void TimerEnd(){
     UnPause();
}

Upvotes: 0

ikh
ikh

Reputation: 2436

One way to do this is without a timer at all. Create a loop that makes the thread sleep for say 25 milliseconds, and then checks whether a key has been pressed via Console.KeyAvailable (which is non-blocking), or until the time between DateTime.Now() and the time of start of the loop has exceeded the timeout.

Upvotes: 3

lesscode
lesscode

Reputation: 6361

One way to do this in C# 4.0:

Task.Factory.StartNew(() => Console.ReadKey()).Wait(TimeSpan.FromSeconds(5.0));

Upvotes: 21

Ankush
Ankush

Reputation: 2554

Start two threads. One listens for keypress and other waits for some time. Make main thread to wait unless any one is done. Then proceed and ignore other thread response. :)

Upvotes: 0

Related Questions