Adam J
Adam J

Reputation: 183

Input polling in a while(true) loop on a different thread only working once

I've created a stop watch app. Within its constructor I've started a new thread that has a while(true) loop to check for keyboard hits - if Space is hit the stopwatch will pause; if A is hit, the stopwatch resumes. This works once for each, however after that it does not register, and it seems the loop is no longer running or something because I put a log inside the while loop (but outside of the if statements) and it does not get printed every loop as I presumed it would. (Note I had to include hasPressedSpace and hasPressedA booleans because the Input events were being registered multiple times during one keystroke).

namespace StopWatch
{
    class Program
    {
        static void Main(string[] args)
        {
            StopWatch stopWatch = new StopWatch();
            stopWatch.Start();
        }
    }

    public class StopWatch
    {
        public TimeSpan Duration { get; private set; }
        private bool _hasStoppped;
        private ThreadStart threadStart;
        private Thread thread;
        private bool isPaused;

        public StopWatch()
        {

            Duration = new TimeSpan();
            threadStart = new ThreadStart(KeyBoardThread);
            thread = new Thread(threadStart);
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
        }

        public void Start()
        {

            while (!_hasStoppped)
                {

                    Thread.Sleep(100);
                    Duration += TimeSpan.FromMilliseconds(100);
                    Console.WriteLine("Duration: " + Duration);

                }
        }


        void KeyBoardThread()
        {

            bool hasPressedSpace = false;
            bool hasPressedA = false;

            while (true)
            {


            if (Keyboard.IsKeyDown(Key.Space) && !hasPressedSpace)
                {

                    hasPressedSpace = true;
                    hasPressedA = false;
                    Stop();
                }

            if (Keyboard.IsKeyDown(Key.A) && !hasPressedA)
                {
                    hasPressedSpace = false;
                    hasPressedA = true;
                    _hasStoppped = false;
                    Start();
                }

            }


            }

         void Stop()
        {
            Console.WriteLine("stop called");
            _hasStoppped = true;

        }
    }
}

Upvotes: 0

Views: 587

Answers (1)

Stephen Kennedy
Stephen Kennedy

Reputation: 21568

Add the following line to the end of your main function:

Console.WriteLine("Exit");

You will observe that after pressing the Space key, the program prints "Exit". Then it, well, exits!

The problem is here:

while (!_hasStoppped)
{
    Thread.Sleep(100);
    Duration += TimeSpan.FromMilliseconds(100);
    Console.WriteLine("Duration: " + Duration);
}

If _hasStoppped is true the thread completes and so does your program. You need to rethink your logic.

You may also like to note that a Stopwatch class is built into the .NET Framework :)

Upvotes: 2

Related Questions