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.