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);
}
}
Which one of the following is not a valid state of a thread? Explanation: None.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With