为什么线程进入 WaitSleepJoin 状态?

kat*_*tit 4 c# multithreading

我正在编写运行后台线程的单例类。以下是它的启动和维护方式:

 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);
            }
        }
Run Code Online (Sandbox Code Playgroud)

我在这个类中调用我的方法,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);
Run Code Online (Sandbox Code Playgroud)

我检查了错误日志,发现异常:

线程正在运行或终止;它无法重新启动。

在调试它说:

----ApplePushNotificatorService.EnsureBackgroundThread 线程状态:背景,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);
            }
        }
Run Code Online (Sandbox Code Playgroud)

Ser*_*rvy 5

状态告诉我们线程当前正在休眠,可能在您对 的调用之一中Sleep。这意味着它仍在运行。因为它仍在运行,所以您无法启动它。您正在尝试多次启动同一个线程。你不能那样做。你开始它一次,然后它就开始了,就是这样。尝试在运行时或完成后再次启动它是不可能的。


Dan*_*zey 2

很简单,正如错误所述:您的线程已创建并正在运行或终止 - 然后您尝试再次启动它。

大概在你的TestClass单例类中有多个调用(我猜这可能在apns.Send调用下的某个地方)。第一次调用时EnsureBackgroundThread,将创建并启动一个线程。下次调用时将在同一线程上EnsureBackgroundThread调用,从而导致相同的错误。Thread.Start

这里可能需要注意的是,当线程完成时,引用它的变量不会设置为null- 但更有可能的是,您只是EnsureBackgroundThread多次调用该方法,而您编写的代码不支持这一点。