Ich habe eine Methode void DoWork(object input)
, die ungefähr 5 Sekunden dauert. Ich habe gelesen, dass Thread
für diese längeren Operationen besser geeignet ist als ThreadPool
, aber ich habe ein Problem festgestellt.
Ich klicke auf eine Schaltfläche, die threadRun.Start(input)
aufruft, die ausgeführt wird und die Feinabstimmung beendet. Ich klicke erneut auf die Schaltfläche und erhalte die folgende Ausnahme:
Thread is running or terminated; it cannot restart.
Können Sie einen Thread nicht "wiederverwenden"? Soll ich ThreadPool verwenden? Warum ist Thread "besser für längere Operationen geeignet" als ThreadPool? Wenn Sie einen Thread nicht wiederverwenden können, warum sollte er überhaupt verwendet werden (d. H. Welche Vorteile bietet er)?
Können Sie einen Thread nicht "wiederverwenden"?
Sie können. Aber Sie müssen den Thread so programmieren, dass er nicht beendet wird, sondern stattdessen auf mehr Arbeit wartet. Das ist was ein Thread-Pool tut.
Soll ich ThreadPool verwenden?
Wenn Sie einen Thread erneut verwenden möchten, ja.
Warum ist Thread im Vergleich zu ThreadPool "besser für längere Operationen geeignet"?
Stellen Sie sich einen Thread-Pool vor, der eine große Anzahl von schnellen Operationen bereitstellt. Sie möchten nicht zu viele Threads haben, weil der Computer nur so viele Dinge gleichzeitig tun kann. Bei jeder langen Operation, die Sie im Threadpool vornehmen, wird ein Thread aus dem Pool gebunden. Also muss der Pool entweder viele zusätzliche Threads haben oder es kann zu wenig Threads laufen. Weder führt zu einem effizienten Thread-Pool-Design.
Bei längeren Operationen ist der Aufwand zum Erstellen und Löschen eines Threads im Vergleich zu den Kosten der Operation sehr gering. Der normale Nachteil der Verwendung eines Threads nur für die Operation gilt nicht.
Wenn Sie einen Thread nicht wiederverwenden können, warum sollte er überhaupt verwendet werden (d. h. welche Vorteile bietet er)?
Ich gehe davon aus, dass Sie einen Thread verwenden, der einem Job zugeordnet ist, der dann mit einem Thread-Pool beendet wird. Der Vorteil ist, dass die Anzahl der Threads immer der Anzahl der Jobs auf diese Weise entspricht. Das bedeutet, dass Sie jedes Mal, wenn Sie einen Job starten, einen Thread erstellen und einen Thread jedes Mal zerstören müssen, wenn Sie einen fertig haben, aber Sie haben keine zusätzlichen Threads, noch werden Ihnen Threads knapp. (Dies kann eine gute Sache mit I / O-gebundenen Threads sein, kann aber eine schlechte Sache sein, wenn die meisten Threads die meiste Zeit CPU-gebunden sind.)
Thread.Start Dokumentation sagt:
Sobald der Thread beendet ist, kann er nicht mit einem anderen Anruf neu gestartet werden zu starten.
Threads sind nicht wiederverwendbar. Ich habe dieses Problem schon vor einiger Zeit gemeistert. Die Lösung bestand darin, bei Bedarf eine neue Thread
-Instanz zu erstellen.
Wie die Nachricht besagt, können Sie den Thread nicht neu starten. Sie können einfach einen neuen Thread für Ihre nächste Operation erstellen. Oder Sie denken über ein Design nach, bei dem der Hintergrundthread weiterarbeitet, bis alle Ihre Aufgaben abgeschlossen sind, anstatt für jeden einen neuen Thread zu starten.
Es sieht von vornherein so aus.
Ich stieß auf das gleiche Problem und die einzige Lösung, die ich finden konnte, war, den Thread neu zu erstellen. In meinem Fall habe ich den Thread nicht oft neu gestartet, also habe ich nicht weiter gesucht.
Eine Suche ist nun dieser Thread aufgetaucht auf social.msdn , wo die angenommene Antwort lautet:
Ein gestoppter oder abgebrochener Thread kann nicht erneut angegeben werden.
Das MSDN wiederholt dies ebenfalls:
Der Versuch, einen abgebrochenen Thread durch einen Aufruf von Start für einen Thread, der beendet wurde, zu starten, löst eine ThreadStateException aus.
for(;;){}
oder while(true){}
sind nützliche Konstrukte, um einen Thread wiederzuverwenden. In der Regel wartet der Thread auf ein Synchronisierungsobjekt am Anfang dieser Schleifen. In Ihrem Beispiel könnten Sie auf ein Event oder Semaphor warten und es über Ihre Schaltfläche OnClick()
handler signalisieren.
Es ist nur im Hintergrundmodus. Es scheint, dass Sie den ThreadPool verwenden müssen, da das erneute Starten und Neu-Erstellen von Thread-Objekten sehr kostspielig ist. Wenn Sie einen Job mit langer Laufzeit haben, der länger dauert als Ihr Hauptprozess, sollten Sie einen Windows-Dienst verwenden.
Tags und Links c# multithreading