C #, Ereignishandler und Threading

8

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?

    
anonymous coward 01.07.2009, 06:15
quelle

2 Antworten

11

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:

%Vor%     
Jon Skeet 01.07.2009, 06:24
quelle
6

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

    
Oliver Hanappi 01.07.2009 06:18
quelle