2010-02-09 6 views
7

Ich habe eine .NET-winforms-Anwendung geschrieben, die einen sekundären Thread verwendet, um eine schwere Verarbeitung durchzuführen, die den Fortschritt an den UI-Thread zurückgibt. Alles funktioniert korrekt, das Formular zeigt den Fortschritt an, und ich habe auch eine Abbrechen-Schaltfläche erstellt, um den Verarbeitungs-Thread zu unterbrechen. Wenn jedoch der zeitaufwändige Prozess die Anwendung durchläuft und mein gesamter Computer langsamer wird. Es dauert eine lange Zeit, Fenster zu ziehen, und es gibt sogar eine erhebliche Verzögerung beim Versuch, Buchstaben in Notepad zu schreiben.Ändern der Threadpriorität, um mein Programm und den Computer reaktionsfähiger zu machen

Ich nehme an, ich muss die Priorität des Verarbeitungsthreads reduzieren und/oder die Priorität des UI-Threads erhöhen. Ist das richtig? Im Moment haben beide Threads die Priorität Normal.

Ist es genauso einfach wie das folgende? Oder sollte ich etwas anderes tun?

Thread.CurrentThread.Priority = ThreadPriority.AboveNormal; 

Wie sollte ich die Prioritäten ändern? Soll ich die Priorität der Verarbeitung reduzieren oder die Priorität der Benutzeroberfläche oder beides erhöhen? Und zu welcher Einstellung? Über Normal oder am höchsten?

+0

Eric, welche Art von Prozessor ist in Ihrer Entwicklungsmaschine? Wie oft kommuniziert der Worker Thread zurück zur Benutzeroberfläche? – overslacked

Antwort

0

Normalerweise möchten Sie die Priorität Ihres Hauptthreads in Ruhe lassen und die Priorität des Verarbeitungs-Threads auf Idle reduzieren.

+0

Wenn Sie es auf Leerlauf stellen, dauert eine lange, rechenintensive Routine viel länger. Besser, es auf BelowNormal einzustellen. –

+0

@Reed: Es wird normalerweise keinen Unterschied zwischen den beiden geben. Der einzige Unterschied besteht darin, dass es einen weiteren Thread gibt, der die Priorität "Idle" oder "BelowNormal" hat - keine der beiden ist besonders häufig. –

+0

Bei BelowNormal gibt es einige Dienste. Ich habe tatsächlich einen merklichen Unterschied in meinem Code gefunden ... –

1

Wenn Sie möchten, dass der Hintergrundthread die Systemreaktionsfähigkeit insgesamt nicht beeinflusst, müssen Sie die Priorität verringern, am wahrscheinlichsten, indem Sie die Priorität auf BelowNormal setzen.

Andernfalls wird es den gleichen Effekt haben, den Sie gerade sehen.

Das gesagt, würde ich zögern, dies in meinem eigenen Code zu tun. Wenn Ihr Programm auf einem System mit mehreren Prozessorkernen ausgeführt wird, ist dies wahrscheinlich kein Problem. Wenn Sie die Threadpriorität (möglicherweise) verringern, dauert die Verarbeitung Ihres Algorithmus länger.

5

Ich denke nicht unbedingt Thread Priorität ist Ihr Problem (obwohl es ein Teil davon sein könnte). Sehen Sie sich diese SO-Frage an: Background Worker Thread Priority.

Es ist wahrscheinlich zu eng Schleifen in Ihrem Hintergrund Thread, die CPU-Zeit auf diesem Thread halten. Es gibt mehrere Möglichkeiten, um es von den brutalen (Thread-Schlaf) zu den vernünftigeren (Mutex und Ereignisse) zu beheben.

Sie können auch versuchen, den Hintergrund-Thread (entweder direkt oder in einer Testumgebung) zu profilieren, um zu sehen, wo er die meiste Zeit verbringt. Versuchen Sie, dies mit asynchronen Ereignissen oder ähnlichen Entladetechniken zu isolieren.

+0

+1 - das ist die beste Lösung – Tim

+0

Wenn die Arbeit wirklich "schwere Verarbeitung" ist, wie angegeben, dann wird der Versuch, Mutexe und Ereignisse usw. zu verwenden, die Verarbeitung nur dramatisch verlangsamen. Die CPU voll auszunutzen, ist keine schlechte Sache - unnötigerweise ist das Problem ... –

+0

Es hängt von der Definition von "schwerer Verarbeitung" ab. Ich stimme Ihnen zu, obwohl Reed, wenn Sie bereits eng investiert sind, das Hinzufügen zusätzlicher Kontextwechsel nur noch verschlimmern wird. Es ist jedoch meine Erfahrung, dass manchmal sorgfältig angewandte Segmentierung der Arbeit (unter Verwendung von Mutexen und Signalen) Prozessorkonflikte lindern kann, ohne die Geschwindigkeit signifikant zu beeinflussen, obwohl es immer etwas Verlust geben wird. – GrayWizardx

0

Normalerweise sollten Sie die Priorität des Worker-Threads auf eine gute Stufe setzen (zB möchte der Benutzer etwas in einer anderen Anwendung machen und sogar der Worker-Thread sollte nett sein), obwohl Windows bereits die "aktiven" Prozesse verstärkt thread (die Anwendung haben Sie ein Fenster mit Eingabefokus) ein wenig, so dass es sich ansprechender fühlen. Die höheren Prioritäten werden normalerweise benötigt, wenn Sie einige Zeitbeschränkungen einhalten müssen.

+0

Auch eine Anmerkung (nicht das Hauptproblem): Sie sollten wissen, dass Threads mit unterschiedlichen Prioritäten seltsame Nebenläufigkeitsprobleme haben können (Dinge wie: Was ist, wenn ein Thread mit einem niedrigeren prio einen kritischen Abschnitt ergreift und nie wieder als normal geplant wird oder höher prio thread nimmt die gesamte CPU) –

+0

@Ritsaert: Der Windows-Scheduler hat "Verhungern Prävention", so dass, selbst wenn etwas auf niedrige Priorität gesetzt ist, seine Priorität gelegentlich "gestoßen" wird, so dass es laufen und (schließlich) freigeben der kritische Abschnitt/Mutex/was auch immer es hält. –

+0

@Jerry: Danke für die Zugabe. Ich weiß, dass neuere Windows-Versionen das haben, aber selbst wenn das vorhanden ist, kann es für relativ lange Zeit Sperren halten. –

Verwandte Themen