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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13170/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-01 08:45:23  来源:igfitidea点击:

A ThreadStateException occures when trying to restart a thread

提问by rjzii

From time to time I get a System.Threading.ThreadStateException when attempting to restart a thread. The code in question is as follows:

尝试重新启动线程时,我有时会收到 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); 
}

So two questions - is this the correct way of doing things, and it is, is there a way to prevent the error from occurring?

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

采纳答案by Lasse V. Karlsen

The problem is that you have code that first checks if it should create a new thread object, and another piece of code that determines wether to start the thread object. Due to race conditions and similar things, your code might end up trying to call .Start on an existing thread object. Considering you don't post the details behind the checkvariable, it's impossible to know what might trigger this behavior.

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

You should reorganize your code so that .Start is guaranteed to only be called on new objects. In short, you should put the Start method into the same if-statement as the one that creates a new thread object.

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

Personally, I would try to reorganize the entire code so that I didn't need to create another thread, but wrap the code inside the thread object inside a loop so that the thread just keeps on going.

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

回答by Brad Wilson

A ThreadStateException is thrown because you're trying to start a thread that's not in a startable state. The most likely situations would be that it's already running, or that it has fully exited.

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

There are potentially a couple things that might be happening. First is, the thread might have transitioned from Running to StopRequested, which isn't fully stopped yet, so your logic doesn't create a new thread, and you're trying to start a thread which has just finished running or is about to finish running (neither of which is a valid state for restarting).

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

The other possibility is that the thread was aborted. Threads which are aborted go to the Aborted state, not the Stopped state, and of course are also not valid for restarting.

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

Really, the only kind of thread that is still alive that can be "restarted" is one that's suspended. You might want to use this conditional instead:

确实,唯一一种可以“重新启动”的仍然活动的线程是挂起的线程。您可能想改用此条件:

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

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

回答by John Richardson

It's possible for a thread to be in more than one state at once therefore the ThreadState property is actually a bitmap of possible states. So testing for equality with just one state will not give you the right result. You would need to do something like:

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

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

However, checking thread state is the wrong to do anything. I'm not entirely clear what you're trying to achieve but I will guess that you're waiting for a thread to terminate before restarting it. In that case you should do:

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

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

Although if you describe the problem you're trying to solve in more detail I'm almost certain there will be a better solution. Waiting around for a thread to end just to restart it again doesn't seem that efficient to me. Perhaps you just need some kind of inter-thread communication?

尽管如果您更详细地描述要解决的问题,我几乎可以肯定会有更好的解决方案。等待一个线程结束只是为了再次重新启动它对我来说似乎没有那么有效。也许您只需要某种线程间通信?

John.

约翰。