warum gibt es keinen EndInvoke im Cross Thread-UI-Komponentenaufruf?

7

Ich habe versucht, einer ListBox, die ich in meiner Anwendung habe, eine Zeichenfolge hinzuzufügen (simple winform) - und ich habe es mit BeginInboke gemacht

%Vor%

Nachdem ich diese 3 Zeilen wieder gelesen habe - und ich verstehe nicht warum in jedem Beispiel von Cross thread UI, dass ich auf Google und auf MSDN sehe, sehe ich keinen Aufruf von EndInvoke? Gibt es einen Grund, die EndInvoke nicht in diesem Fall aufzurufen?

    
Yanshof 02.08.2013, 12:02
quelle

2 Antworten

16

Dies war eine unglückliche Namenswahl in .NET. Die Methoden Control.BeginInvoke und Dispatcher.BeginInvoke haben denselben Namen wie die Methoden eines Stellvertreters, sind jedoch vollständig anders. Die Hauptunterschiede:

  • Die BeginInvoke () -Methode eines Delegates ist immer typsicher, sie hat dieselben Argumente wie die Delegat-Deklaration. Dies fehlt vollständig in den Control / Dispatcher-Versionen. Argumente werden über ein params-Array vom Typ object [] übergeben. Der Compiler wird Ihnen nicht sagen, wenn Sie ein Argument falsch erhalten, es bombardiert zur Laufzeit

  • Die Methode Invoke () eines Delegate führt das Delegat-Ziel für denselben Thread aus. Dies ist nicht der Fall für Control / Dispatcher.Invoke (). Sie ordnen den Aufruf dem UI-Thread

  • zu
  • Eine Ausnahme, die in das BeginInvoke () - Ziel eines Delegaten geworfen wird, wird erfasst und führt nicht zum Scheitern des Programms. Wird beim Aufruf von EndInvoke () erneut geworfen. Dies ist bei Control / Dispatcher.BeginInvoke () überhaupt nicht der Fall, sie lösen die Ausnahme im UI-Thread aus. Ohne einen vernünftigen Weg, die Ausnahme zu fangen, ist einer der größeren Gründe, dass Application.UnhandledException existiert.

  • Wenn die EndInvoke () -Methode eines Delegierten aufgerufen wird, erforderlich , führt dies zu einem 10-minütigen Ressourcenleck, wenn Sie dies nicht tun. Es ist nicht erforderlich für die Control / Dispatcher.BeginInvoke () -Methoden und Sie tun dies in der Praxis nie.

  • Die Verwendung von Control / Dispatcher.Invoke () ist riskant, es kann leicht zu einem Deadlock führen. Wird ausgelöst, wenn der UI-Thread nicht zum Aufrufen des Ziels bereit ist und etwas Unkluges ausführt, wie das Warten auf den Abschluss eines Threads. Kein Problem für einen Delegaten, nicht zuletzt, weil die Methode Invoke () keinen Thread verwendet.

  • Der Aufruf von Control / Dispatcher.BeginInvoke () im UI-Thread ist ein unterstütztes Szenario. Das Ziel wird weiterhin erwartungsgemäß im UI-Thread ausgeführt. Aber später, nachdem der UI-Thread wieder in den Leerlauf geht und wieder in die Dispatcher-Schleife eintritt. Dies ist ein sehr nützliches Feature, das trickreiche Re-Entrance-Probleme löst. Insbesondere in Ereignisbehandlungsroutinen für UI-Steuerelemente, die sich beim Ausführen von Code mit zu vielen Nebenwirkungen nicht richtig verhalten.

Eine große Liste mit umfangreichen Implementierungsdetails. Die TLDR-Version ist sicherlich: "Sie haben nichts gemeinsam, EndEnvoke nicht aufrufen ist in Ordnung und ganz normal".

    
Hans Passant 02.08.2013, 14:31
quelle
5

Control.BeginInvoke scheint nicht vollständig zu folgen Gewöhnlich BeginX / EndX Muster aka die Asynchrones Programmiermodell (APM) . In der Regel müssen Sie % EndX aufrufen, im Fall von BeginX ist dies jedoch nicht unbedingt erforderlich:

  

"Sie können Control.BeginInvoke aufrufen, um den Rückgabewert vom Delegaten abzurufen, falls erforderlich , dies ist jedoch nicht erforderlich . EndInvoke wird blockieren, bis der Rückgabewert abgerufen werden kann.

     

- im Abschnitt "Hinweise" auf der MSDN-Referenzseite für EndInvoke (Hervorhebung durch ich)

Und in der Praxis ist es fast nie notwendig. Dies liegt daran, dass die Methode normalerweise aufgerufen wird, um Code auf dem UI-Thread ausführen zu lassen, der die Benutzeroberfläche aktualisiert. Das Aktualisieren der Benutzeroberfläche führt normalerweise nicht zu einem Rückgabewert, daher möchten Sie Control.BeginInvoke nicht aufrufen.

    
stakx 02.08.2013 12:07
quelle

Tags und Links