尝试重新启动线程时发生ThreadStateException

尝试重新启动线程时,我不时会收到System.Threading.ThreadStateException。 有问题的代码如下:

// Make sure the thread is done stopping while (this.mThread.ThreadState == ThreadState.Running) { Thread.Sleep(0); } // Respawn a thread if the current one is stopped or doesn't exist if (this.mThread == null || this.mThread.ThreadState == ThreadState.Stopped) { this.mThread = new Thread(new ParameterizedThreadStart(Monitor)); } // Start the thread if (check) { this.mThread.Start(60000); } else { this.mThread.Start(0); } 

所以有两个问题 – 这是正确的做事方式,而且,有没有办法防止错误发生?

问题是你有代码首先检查它是否应该创建一个新的线程对象,另一段代码确定是否启动线程对象。 由于竞争条件和类似的事情,您的代码可能最终尝试在现有线程对象上调用.Start。 考虑到你没有在check变量后面发布细节,就不可能知道什么可能触发这种行为。

您应该重新组织代码,以便保证只在新对象上调用.Start。 简而言之,您应该将Start方法放入与创建新线程对象的if语句相同的if语句中。

就个人而言,我会尝试重新组织整个代码,这样我就不需要创建另一个线程,而是将代码包装在一个循环内的线程对象中,这样线程就会继续运行。

一个线程可能同时处于多个状态,因此ThreadState属性实际上是可能状态的位图。 因此,只用一种状态来测试相等性就不会给你正确的结果。 您需要执行以下操作:

 if((mThread.ThreadState & ThreadState.Running) != 0) 

但是,检查线程状态是做错的。 我并不完全清楚你想要实现的目标,但我猜你正在等待一个线程在重新启动之前终止。 在这种情况下,你应该这样做:

 mThread.Join(); mThread = new Thread(new ParameterizedThreadStart(Monitor)); if(check) mThread.Start(60000); else mThread.Start(0); 

虽然如果你描述问题,你试图更详细地解决,我几乎可以肯定会有更好的解决方案。 等待一个线程结束只是为了重新启动它对我来说似乎并不高效。 也许你只需要某种线程间的通信?

约翰。

抛出ThreadStateException是因为您尝试启动一个不处于可启动状态的线程。 最可能的情况是它已经在运行,或者已经完全退出。

可能会发生一些事情。 首先,线程可能已从Running转换为StopRequested,但尚未完全停止,因此您的逻辑不会创建新线程,并且您正在尝试启动刚刚运行或即将运行的线程完成运行(两者都不是重启的有效状态)。

另一种可能性是线程被中止。 中止的线程进入Aborted状态,而不是Stopped状态,当然也无法重启。

真的,唯一一种可以“重启”的活着的线程是暂停的。 您可能希望使用此条件:

if (this.mThread == null || this.mThread.ThreadState != ThreadState.Suspended)