Ich schreibe eine kleine Chat-App, und ich habe diesen Event-Handler:
%Vor% o_Typing
ist eine Methode in einer Klasse, die von TabPage
abgeleitet ist. Grundsätzlich möchte ich, dass jede Konversation einen eigenen Tab hat.
Die Ereignishandler werden von meinem Chat-Objekt ausgelöst, das in einem anderen Thread ausgeführt wird. Ich habe 1 Thread für die Benutzeroberfläche und einen weiteren Thread für jede Chat-Konversation (um den Server nach neuen Daten abzufragen)
Wenn das Ereignis ausgelöst wird, wird MessageBox
angezeigt, aber die Beschriftung des Tabs ändert sich nicht. Nachdem das Ereignis einmal ausgelöst wurde, wird es nie mehr ausgelöst. Dies lässt mich glauben, dass das Ereignis im Worker-Thread aufgerufen wird, obwohl es im UI-Thread definiert ist.
Wie kann ich meine Ereignisse vom Worker-Thread abrufen lassen und Invoke()
verwenden, um sie im UI-Thread auszuführen?
Es gibt zwei Optionen:
1) Machen Sie die Event-Handler threadsicher: Verwenden Sie Control.Invoke/BeginInvoke
in jedem Event-Handler, der mit dem UI-Thread kommunizieren muss.
2) Versetzen Sie das Worker-Thread-Marshal zurück in den Benutzeroberflächenthread, bevor Sie das Ereignis auslösen. Verwenden Sie also Control.Invoke
als Teil des Prozesses zum Auslösen des Ereignisses, sodass die Ereignishandler in der Benutzeroberfläche aufgerufen werden Faden. Je nachdem, wie Ihre App strukturiert ist, möchten Sie vielleicht nicht, dass Ihre ereigniserhöhende Komponente explizit von der Benutzeroberfläche erfährt - aber wenn sie erstellt wird, können Sie eine ISynchronizeInvoke
übergeben (welche Control
implementiert) und Ihre Komponente kann diese verwenden seine Ereignisse auf den richtigen Thread zu heben. Das funktioniert natürlich (einfach), wenn jeder Event-Handler gerne auf demselben Thread läuft - aber das wird oft der Fall sein. Du würdest etwas schreiben wie:
Wenn Sie Ihr Ereignis in Code auslösen, der von Ihrem Arbeitsthread ausgeführt wird, werden alle Methoden, die das Ereignis abonniert haben, unter diesem Arbeitsthread ausgeführt.
Für GUI-Elemente müssen Sie sich die Invoke-Methoden ansehen.
Beste Grüße
Tags und Links c# multithreading events worker-thread