我正在编写运行后台线程的单例类。以下是它的开始和维护方式:
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);
}
}
我在TestClass
这个类中调用我的方法,如下所示:
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);
我查看了错误日志,并看到了异常:
线程正在运行或终止;它无法重启。
在调试中它说:
---- ApplePushNotificatorService.EnsureBackgroundThread ThreadState:Background,WaitSleepJoin
为什么进入“WaitSleepJoin”状态?是因为我在测试中做了“Thread.Sleep”吗?
保持线程活着的代码看起来是否正确?我该如何解决这个问题?这个想法是在单例调用“发送”方法时 - 我们需要确保后台线程正在运行。
编辑:
这是重新正常工作的代码
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);
}
}
答案 0 :(得分:4)
状态告诉我们线程当前正在休眠,可能是在您对Sleep
的一次调用中。这意味着它仍在运行。因为它仍在运行,所以无法启动它。你试图多次启动同一个线程。你不能这样做。你启动它一次,然后它就开始了,就是这样。尝试在第二次启动它时,无论是在运行时还是在完成之后,都是不可能的。
答案 1 :(得分:2)
很简单,因为错误声明:您的线程已经创建并且正在运行或终止 - 然后您尝试再次启动它。
大概在你的TestClass
你有多次打电话给你的单身人士课(我猜这可能是在apns.Send
电话下的某个地方)。第一次调用EnsureBackgroundThread
时,将创建并启动单个线程。下次您致电EnsureBackgroundThread
时,会在同一线程上拨打Thread.Start
,从而导致同样的错误。
这里可能需要注意的是,当一个线程完成时,引用它的变量不会设置为null
- 但更有可能你只是多次调用EnsureBackgroundThread
方法而且你写的代码不支持。