ThreadStateException vyskytuje při pokusu o restart vlákno

hlasů
6

Čas od času jsem si System.Threading.ThreadStateException při pokusu o restart vlákno. Kód v pochybnost je následující:

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

Takže dvě otázky - je to správný způsob, jak dělat věci, a to znamená, že existuje způsob, jak zabránit chybě?

Položena 16/08/2008 v 16:24
zdroj uživatelem
V jiných jazycích...                            


3 odpovědí

hlasů
6

Je možné, aby nit, že ve více než jednom státě najednou tedy vlastnost ThreadState je vlastně bitmap z možných stavů. Takže testování rovnosti s jediným státem nebude vám ten správný výsledek. Budete muset udělat něco jako:

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

Nicméně, kontrola nit stav je špatný nic dělat. Nejsem si zcela jasné, co se snažíte dosáhnout, ale já myslím, že čekáte na vlákno ukončit před restartováním. V takovém případě byste měli udělat:

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

I když, pokud jste popsat problém, který se snažíte řešit podrobněji Jsem si téměř jistý, že bude lepší řešení. Čekání na niti na konec, jen aby jej restartovat znovu se nezdá, že efektivní pro mě. Možná, že stačí nějaký inter-thread komunikaci?

John.

Odpovězeno 16/08/2008 v 17:25
zdroj uživatelem

hlasů
3

Problém je v tom, že máte kód, který nejprve zkontroluje, zda by měl vytvořit novou nit objekt, a další kus kódu, který určuje wether ke spuštění objektu závitu. Vzhledem k závodních podmínkách a podobné věci, váš kód může skončit se snaží zavolat .Start na existující vlákna objektu. Vzhledem k tomu, nemusíte psát údaje za sebou na check proměnné, to je nemožné vědět, co by mohlo vyvolat toto chování.

Ty by měly reorganizovat svůj kód tak, aby .Start je zaručeno, že bude zavolána pouze pro nové objekty. Stručně řečeno, měli byste si dát metodu start do stejného If-prohlášení jako ten, který vytvoří nové vlákno objekt.

Osobně bych se snaží reorganizovat celý kód, takže jsem nemusel vytvořit další vlákno, ale zabalit kód uvnitř objektu vlákna uvnitř smyčky, takže nit prostě pořád dál.

Odpovězeno 16/08/2008 v 18:56
zdroj uživatelem

hlasů
1

ThreadStateException je vyvolána, protože se snažíte spustit vlákno, které není ve spouštěcí stavu. Jako nejpravděpodobnější situace by bylo, že se to již běží, nebo že se úplně ukončen.

Tam jsou potenciálně pár věcí, které by mohly být děje. První z nich je, nit mohla přešli od spuštění do StopRequested, což není zcela zastaven ještě, takže vaše logika nevytváří nové vlákno, a snažíte se začít závit, který právě dokončil běh nebo se chystá dokončení spuštění (z nichž ani jeden není platný stát pro restartování).

Druhou možností je, že vlákno bylo přerušeno. Nitě, které jsou přerušeny jít do přerušena státu, nikoli stavu zastavení, a samozřejmě také neplatí pro restartování.

Ve skutečnosti, jediný druh závitu, který je stále naživu, které mohou být „restartování“, je ten, který je pozastaven. Možná budete chtít, aby použil to podmíněno:

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

Odpovězeno 16/08/2008 v 17:18
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more