7 Stimmen

Beim Versuch, einen Thread neu zu starten, tritt eine ThreadStateException auf

Von Zeit zu Zeit erhalte ich eine System.Threading.ThreadStateException, wenn ich versuche, einen Thread neu zu starten. Der betreffende Code lautet wie folgt:

// 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); 
}

Daher zwei Fragen: Ist dies die richtige Vorgehensweise, und wenn ja, gibt es eine Möglichkeit, diesen Fehler zu verhindern?

7voto

John Richardson Punkte 1635

Es ist möglich, dass sich ein Thread in mehr als einem Zustand gleichzeitig befindet, daher ist die Eigenschaft ThreadState eigentlich eine Bitmap der möglichen Zustände. Wenn Sie also mit nur einem Zustand auf Gleichheit prüfen, erhalten Sie nicht das richtige Ergebnis. Sie müssten etwas tun wie:

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

Die Überprüfung des Thread-Status ist jedoch der falsche Weg, um etwas zu tun. Mir ist nicht ganz klar, was Sie zu erreichen versuchen, aber ich vermute, dass Sie auf die Beendigung eines Threads warten, bevor Sie ihn neu starten. In diesem Fall sollten Sie das tun:

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

Aber wenn Sie das Problem, das Sie lösen wollen, genauer beschreiben, bin ich mir fast sicher, dass es eine bessere Lösung geben wird. Auf das Ende eines Threads zu warten, nur um ihn dann wieder neu zu starten, scheint mir nicht sehr effizient zu sein. Vielleicht brauchen Sie einfach eine Art von Inter-Thread-Kommunikation?

Johannes.

3voto

Lasse V. Karlsen Punkte 364542

Das Problem ist, dass Sie einen Code haben, der zunächst prüft, ob ein neues Thread-Objekt erstellt werden soll, und einen weiteren Code, der bestimmt, ob das Thread-Objekt gestartet werden soll. Aufgrund von Race Conditions und ähnlichen Dingen könnte Ihr Code am Ende versuchen, .Start für ein bestehendes Thread-Objekt aufzurufen. Wenn man bedenkt, dass Sie nicht die Details hinter dem siehe Variable ist es unmöglich zu wissen, was dieses Verhalten auslösen könnte.

Sie sollten Ihren Code so umgestalten, dass .Start garantiert nur bei neuen Objekten aufgerufen wird. Kurz gesagt, Sie sollten die Start-Methode in dieselbe if-Anweisung einfügen wie diejenige, die ein neues Thread-Objekt erzeugt.

Ich persönlich würde versuchen, den gesamten Code so umzugestalten, dass ich keinen weiteren Thread erstellen muss, sondern den Code innerhalb des Thread-Objekts in eine Schleife verpacken, damit der Thread einfach weiterläuft.

1voto

Brad Wilson Punkte 64944

Eine ThreadStateException wird ausgelöst, weil Sie versuchen, einen Thread zu starten, der sich nicht in einem startbaren Zustand befindet. Die wahrscheinlichste Situation ist, dass der Thread bereits läuft oder vollständig beendet wurde.

Möglicherweise gibt es ein paar Dinge, die hier geschehen könnten. Erstens könnte der Thread von "Running" zu "StopRequested" übergegangen sein, was noch nicht vollständig gestoppt ist, so dass Ihre Logik keinen neuen Thread erstellt, und Sie versuchen, einen Thread zu starten, der gerade zu Ende gelaufen ist oder kurz davor steht, zu Ende zu laufen (beides ist kein gültiger Zustand für einen Neustart).

Die andere Möglichkeit ist, dass der Thread abgebrochen wurde. Abgebrochene Threads gehen in den Zustand "Aborted" und nicht in den Zustand "Stopped" über und sind natürlich auch nicht für einen Neustart geeignet.

Die einzige Art von Thread, die noch am Leben ist und "neu gestartet" werden kann, ist ein Thread, der ausgesetzt wurde. Sie sollten stattdessen diese Bedingung verwenden:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X