Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why thread enters WaitSleepJoin state?

I'm coding singleton class that runs a background thread. Here is how it started and maintained:

 private void EnsureBackgroundThread()
        {
            try
            {
                if (this.RunnerThread == null)
                    this.RunnerThread = new Thread(this.BackgroundRunner) { IsBackground = true };

                if (this.RunnerThread.ThreadState != ThreadState.Running)
                {
                    Debug.WriteLine("----ApplePushNotificatorService.EnsureBackgroundThread ThreadState: " + this.RunnerThread.ThreadState);
                    this.RunnerThread.Start();
                }
            }
            catch (Exception ex)
            {
                this.LoggerService.Log(null, ex);
            }
        }

I call my method in this class from TestClass like so:

apns.Send("dev", devices, "Testing...", out badIds);

            // Wait 5 seconds to let it send stuff through.
            Thread.Sleep(5000);

            devices.Clear();
            devices.Add("some bad id");

            // Now let's call this again, but this time we should get back some bad Ids
            apns.Send("dev", devices, "Testing...", out badIds);

            // Wait 5 seconds to let it send stuff through.
            Thread.Sleep(5000);

            devices.Clear();
            devices.Add("9edc21d0d4e369f50040c5d2c94f2ea29c7d596090e4ddae253712cd406391df");
            apns.Send("dev", devices, "Test message for Andrew's phone", out badIds);

            // Wait 5 seconds to let it send stuff through.
            Thread.Sleep(5000);

I checked error logs and I see exceptions:

Thread is running or terminated; it cannot restart.

In debug it says:

----ApplePushNotificatorService.EnsureBackgroundThread ThreadState: Background, WaitSleepJoin

Why does it enter "WaitSleepJoin" state? Is it because I do "Thread.Sleep" in my test?

Does my code to keep thread alive look correct? How do I work around this? The idea is when "Send" method called on singleton - we need to make sure background thread is running.

EDIT:

This is re-worked code that is working properly

private void EnsureBackgroundThread()
        {
            try
            {
                if (this.RunnerThread != null && this.RunnerThread.IsAlive) return;
                this.RunnerThread = new Thread(this.BackgroundRunner) { IsBackground = true };
                this.RunnerThread.Start();
            }
            catch (Exception ex)
            {
                this.LoggerService.Log(null, ex);
            }
        }
like image 781
katit Avatar asked Mar 05 '14 16:03

katit


People also ask

Which of these is not a valid ThreadState?

Which one of the following is not a valid state of a thread? Explanation: None.


2 Answers

The state tells us that the thread is currently sleeping, likely in one of your calls to Sleep. This means it's still running. Because it's still running, you cannot start it. You're trying to start the same thread multiple times. You can't do that. You start it once, then it's started, and that's that. Trying to start it a second time, either while it's running, or after it is done, is not possible.

like image 78
Servy Avatar answered Nov 15 '22 01:11

Servy


Quite simply, as the error states: your thread has been created and is running or terminated - and then you try to start it again.

Presumably in your TestClass you have multiple calls to your singleton class (I'm guessing this may be somewhere under the apns.Send call). The first time you call EnsureBackgroundThread, a single thread will be created and started. The next time you call EnsureBackgroundThread will call Thread.Start on the same thread, thus causing the same error.

It's perhaps important to note here that, when a thread completes, the variable referencing it isn't set to null - but more likely you're just calling the EnsureBackgroundThread method more than once and the code you've written doesn't support that.

like image 40
Dan Puzey Avatar answered Nov 14 '22 23:11

Dan Puzey