2008-08-16 67 views
6

尝试重新启动线程时,我经常会遇到System.Threading.ThreadStateException。有问题的代码如下:尝试重新启动线程时发生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); 
} 

所以两个问题 - 这是做事的正确方法,它是,有没有办法来防止错误的发生?

回答

3

的问题是,你有代码,首先检查它是否应该创建一个新的线程对象,另一段代码,确定阉启动线程对象。由于竞争条件和类似的事情,你的代码可能最终试图调用。开始一个现有的线程对象。考虑到您不会在检查变量后发布详细信息,因此无法知道可能会触发此行为。

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

就个人而言,我会尝试重新整理整个代码,所以我并不需要创建另一个线程,但包装线程对象中的代码回路内部,使得线程只是不断去。

1

由于您试图启动不处于可启动状态的线程,因此抛出了ThreadStateException。最有可能的情况是它已经在运行,或者它已经完全退出。

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

另一种可能性是该线程被中止。中止的线程进入中止状态,而不是停止状态,当然也不适用于重新启动。

真的,唯一的一种线程的是还活着,可以“重新开始”是一个已暂停。您可能要改用此条件:

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

6

有可能一个线程在一个以上的国家一下子所以的ThreadState属性实际上是可能的状态的位图。因此,只有一个国家的平等测试不会给你正确的结果。你需要做的是这样的:

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

然而,检查线程状态是错误做任何事情。我并不完全清楚你想达到什么目的,但我会猜测你在等待线程在重新启动之前终止。在这种情况下,你应该做的:

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

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

John。

相关问题