2009-02-26 6 views
0

Ich verstehe, dass in .NET, Control.Invoke (Delegate) verwendet werden muss, um Vorgänge für ein Steuerelement auszuführen. Dies führte mich zu der Frage, in welchen Umgebungen Invoke tatsächlich benötigt wird. Soweit ich weiß, war es in älteren Versionen von Visual Basic und Pascal nicht erforderlich. Insbesondere, was ist der Status von Java (möglicherweise versionsabhängig?) Und "alten Stil" Windows-GUI-Programmierung (manuell Lesen der Nachrichtenwarteschlange)?In welchen Sprachen/Plattformen ist Invoke für GUI-Operationen erforderlich?

Antwort

1

In den meisten Sprachen ist Invoke für GUI-Operationen erforderlich. In Java gibt es SwingUtilities.invokeLater. Eigentlich wäre eine solche Methode in jeder Umgebung notwendig, wenn mehrere Threads verwendet werden. Der Grund dafür ist, dass der Hauptthread der Benutzeroberfläche einen Ereignisbenachrichtigungsmechanismus ausführt. Ein zweiter Thread, um mit diesem Mechanismus interagieren zu können, muss irgendwie damit synchronisiert werden.

Diese Aufrufmethoden sind eigentlich eine Annehmlichkeit für den Entwickler. In Plattformen, die nicht vorhanden sind, bedeutet dies nicht, dass Benutzerelemente aus einem anderen Thread zugreifen dürfen. Es bedeutet möglicherweise nur, dass der Entwickler einen benutzerdefinierten Mechanismus (Senden von Ereignissen) dazu implementieren sollte. UI-Code ist sehr selten Thread-sicher. Ich habe mit vielen Plattformen und Technologien gearbeitet und folge immer dieser Regel: Berühre die Benutzeroberfläche nur mit einem einzigen Thread.

0

Eigentlich nein. Es wird nur benötigt, wenn Ihre GUI mehr als einen Thread ausführt. Bei WinForm- (und WPF-) Anwendungen läuft die GUI auf einem Single-Thread-STA-Thread (dieser stammt aus COM und fragt mich nicht, warum es so ist, denn ich weiß es ehrlich gesagt nicht).

Wenn Sie versuchen, im STA-Thread erstellte Objekte aus einem anderen Thread aufzurufen, werden Überprüfungen durchgeführt, um sicherzustellen, dass eine Ausnahme ausgelöst wird. Das gleiche gilt für WPF, aber WPF macht das sehr viel eleganter.

Wie auch immer, Sie können tatsächlich prüfen, ob Invoke erforderlich ist, da es eine Eigenschaft dafür gibt. Dieses Muster wurde vorgeschlagen, um die Handhabung mehrerer Threads in WinForm-Anwendungen zu erleichtern.

Der obige Code bietet eine umfassende Methode zum Festlegen der Eigenschaft Text, die Sie Ihren Bedürfnissen anpassen können.

+0

Dies hat nichts mit STAthread zu tun oder nicht. Es stimmt, dass STAthread mit COM verwandt ist, aber nur für Interop-Zwecke. Windows erfordert, dass Updates für ein Steuerelement im selben Thread ausgeführt werden wie der Thread, der es erstellt hat, STA oder MTA, spielt keine Rolle. –

1

Sie sind falsch. Control.Invoke ist nicht erforderlich, um Vorgänge an einem Steuerelement auszuführen.

Control.Invoke ist ein nützliches Werkzeug, um Code über Thread-Grenzen hinweg zu marshallen, aber es ist nicht die einzige Möglichkeit, dies zu tun. Sie werden sehen, dass dies am häufigsten verwendet wird, wenn Sie in einem Hintergrundthread arbeiten.

Wenn Sie Code aus einem Hintergrundthread aufrufen, der ein Windowed-Steuerelement aktualisieren muss (dh ein Steuerelement, das über ein Windows-Fensterhandle verfügt und Nachrichten über Message Pump verarbeitet), ändern Sie seine Eigenschaften oder eine andere Manipulation des Steuerelements Sie müssen die Kontrolle an den MessagePump-Thread übergeben, und Control.Invoke ist eine nützliche Möglichkeit, dies zu erreichen.

In ALLE Programme, die unter Windows ausgeführt werden, können Sie nicht Funktionen aufrufen, die Steuerelemente auf einem Hintergrundthread aktualisieren. Einige Sprachen können dieses Detail im Hintergrund behandeln, aber ich weiß nichts davon.

1

Invoke ist nur ein Wrapper um die Win32 API PostMessage. Nur der Thread, der ein Fenster besitzt, darf auf das Fenster zugreifen. Dies ist ein Vermächtnis, das den ganzen Weg zurückführt, als Windows Single-Threading war. Das bedeutet, dass PostMessage der richtige Weg ist, um auf ein echtes Fenster unter Windows zuzugreifen, egal, was Sie verwenden (VB6, Delphi, .NET oder was auch immer), aber die verschiedenen Programmiersprachen bieten Wrapper, die uns das Leben erleichtern.