2010-03-29 13 views

Antwort

6

Der Disponent kann als eine Queue gedacht werden, die Ereignisse gesendet werden; Ein Dispatcher wird auf dem UI-Thread ausgeführt und Ereignisse für die UI ausführen. In Windows können UI-Steuerelemente nur von dem Thread geändert werden, der sie erstellt hat. Änderungen an der Benutzeroberfläche müssen daher vom UI-Thread aus vorgenommen werden. Dies ist einer der kritischen Gründe dafür, dass Vorgänge, die Fensterelemente ändern, an die Benutzeroberflächen gesendet werden müssen Dispatcher.

Ein Hintergrund-Thread wiederum ist ein anderer Thread als die Benutzeroberfläche. Alles, was auf einem dieser Threads ausgeführt wird, wirkt sich nicht auf die Benutzeroberfläche aus oder blockiert sie nicht.

0

Wenn Sie den Dispatcher zum Ausführen einer lang andauernden Operation verwenden, wird er dennoch im UI-Thread nur mit einer anderen Priorität als der aktuellen ausgeführt. Das Problem hierbei ist, dass in der Regel Ihre lang laufende Operation so viel Bandbreite wie möglich haben soll. Unter dem Dispatcher ausgeführt, werden Sie von der Benutzeroberfläche gedrosselt.

Der Dispatcher hat den Zweck, einen Hintergrundthread an die Benutzeroberfläche anzubinden, damit Sie z. B. eine Aktualisierung der Benutzeroberfläche für den Fortschritt Ihrer Operation bereitstellen können.

Wenn Sie einen Vorgang im Hintergrund ausführen und die Ausführung auf die Benutzeroberfläche verschieben möchten, verwenden Sie einen Hintergrundarbeiter oder die neue Aufgabenbibliothek. Verwenden Sie den Dispatcher, um Aktualisierungen zurück auf die Benutzeroberfläche zu übertragen.

2

Das Konzept von BeginInvoke und Invoke kann wie folgt gedacht werden.

  • BeginInvoke bedeutet: „. In der Zukunft dies tun und zurück, bevor es abgeschlossen ich entweder kümmern sich nicht um den Rückgabewert oder Sie können mich an einem gewissen Punkt an dieser Adresse zurückrufen“
  • Invoke bedeutet: "Tun Sie das und ich werde hier sitzen und warten, bis es fertig ist."

Nun, wie sich dies auf Dispatcher und Hintergrundthreads bezieht, ist eine ganz andere Angelegenheit. Wie Justin sagt, verarbeitet der Dispatcher eine Warteschlange mit Dingen, die jedes Mal ausgeführt werden müssen, wenn der UI-Thread inaktiv wird. Ein Hintergrundthread, der BeginInvoke für den Dispatcher aufruft, wird sofort zurückgegeben, obwohl der Dispatcher möglicherweise nicht zur Verarbeitung gelangt ist. Wenn stattdessen Invoke verwendet wurde, würde der Hintergrundthread blockieren, bis der UI-Thread die Verarbeitung abgeschlossen hat. Beachten Sie, dass in Silverlight auf dem Dispatcher keine Invoke-Funktion vorhanden ist und Sie in den meisten Fällen wahrscheinlich nicht möchten, dass Ihr Hintergrund-Thread blockiert wird, während der UI-Thread verarbeitet wird.

Umgekehrt verwendet Delegate.BeginInvoke Worker-Threads im Thread-Pool. Wenn Sie sich im Benutzeroberflächenthread befinden (oder tatsächlich in einem Thread), können Sie BeginInvoke und Invoke für einen Delegaten aufrufen. BeginInvoke wird einen Arbeitsthread verwenden, um den Delegaten unter Verwendung derselben Semantik aufzurufen, die ich oben beschrieben habe. Invoke würde jedoch keinen anderen Thread verwenden. Es würde einfach den Delegaten synchron im Kontext des aufrufenden Threads aufrufen und nach Abschluss zurückkehren.

Seien Sie vorsichtig, wenn Sie die synchrone Ausführung über Threads hinweg verwenden, da dies oft zu Deadlocks führt, wenn Sie nicht besonders vorsichtig sind.

0

Die von beiden Methoden aufgerufenen Vorgänge werden in die Ereigniswarteschlange gestellt, um auf dem UI-Thread ausgeführt zu werden. Invoke wird synchron ausgeführt und blockiert, bis der Vorgang abgeschlossen ist. BeginInvoke wird asynchron ausgeführt, sodass die aufrufende Methode weiterhin ausgeführt werden kann.

Verwandte Themen