2009-03-06 4 views
3

Ich habe einen Tcp-Server, der, wenn ein Client eine Verbindung herstellt, einen neuen Thread erstellt und hinzufügt, aber jedes Mal, wenn ich versuche, auf Informationen über die Verbindung oder irgendetwas darüber zuzugreifen, sagen wir mal, wie viele Clients verbunden sind Ich bekomme eine Cross-Thread-Ausnahme oder etwas ähnliches.C#: Wie kann ich elegant und simpel Cross-Threaded-Aufrufe machen?

Ich lese mehrere Tutorials über Dinge namens Delegaten, Aufruf und Reflexion, aber alle Beispiele oder Tutorials verwirren mich einfach so, dass man einen bestimmten Aufruf ausführt, der in einem anderen fehlschlägt.

Gibt es eine elegante oder einfache Möglichkeit, dies zu tun? Muss ich zuerst lernen, etwas anderes zu tun? Oder mache ich die Dinge viel komplexer als sie sind? Alle Vorschläge, Links oder Tipps werden am meisten geschätzt und akzeptiert.

Antwort

0

Ich vermute, dass Sie diese Cross-Thread-Ausnahme erhalten, da Sie versuchen, Bildschirmelemente von Ihrem Thread-Code zu aktualisieren. Wenn Sie das tun müssen, können Sie eine einfache Lösung mit anonymer Methode erhalten.

Angenommen, Sie möchten ein Element zu einer Listbox namens ListBoxLog hinzufügen. Dieser Code würde den Trick von jedem Thread tun:

ListBoxLog.Invoke((MethodInvoker)delegate { ListBoxLog.Items.Add("Done"); }); 

Es gibt auch eine Eigenschaft .InvokeRequired zu überprüfen, können Sie überprüfen, um zu sehen, ob Aufruf nessecary ist. Normalerweise würden Sie diese Eigenschaft in einer Funktion überprüfen, die sowohl vom Hauptthread der Benutzeroberfläche als auch von einem Hintergrundthread aufgerufen werden kann.

Sie können BeginInvoke auch wie Invoke verwenden. BeginInvoke ist insgesamt asynchron und wartet nicht auf den Abschluss des Codes im Delegaten.

0

Mit Delegierten und Ereignisse.

Das wäre meine beste Antwort.

http://www.codeproject.com/KB/cs/Cross_thread_Events.aspx

+0

Zweitens der CodeProject Artikel, obwohl ich die BackgroundWorker Lösung bevorzuge (auch im Artikel). Nur asynchrones Aufrufen von Ereignissen ist in vielen Fällen jedoch in Ordnung. – OregonGhost

+0

Ich muss zugeben, dass ich nicht viel mit der BackgroundWorker-Klasse gearbeitet habe, aber ich werde mich darum kümmern. Vielen Dank. –

+0

Eigentlich habe ich auch nicht viel mit BackgroundWorker gearbeitet, aber ich habe das gleiche Konzept in meiner letzten größeren Anwendung verwendet und bin damit einverstanden :) – OregonGhost

0

Es gibt viele Beispiele online, Ihnen zu helfen: http://www.google.com/search?q=tcp+server+multi+thread

Wenn C#, die Concurrency and Coordination Runtime (CCR) auch eine Probe über die Implementierung von Multi-Thread-tcp-Server hat. Die CCR ermöglicht ein viel besseres Paradigma zur parallelen Verarbeitung zu implementieren, es vereinfacht eine Menge der Standard-Multithreading-Code.

+0

CCR klingt interessant. Ist es als separater Download verfügbar oder kommt es nur mit dem Robotics Developer Studio? – OregonGhost

+0

Es kommt als Teil des Robotics Developer Studio, aber es ist eine eigene Bibliothek. Sie können es wie jede andere .NET-DLL verwenden. Ich habe gelesen, dass das neue Release (nicht sicher, dass es bereits veröffentlicht wurde) als seperater Download verfügbar sein wird. – Rudi

1

Ich nehme an, Sie gehen direkt von Ihrem Client-Verbindungs-Thread auf die Benutzeroberfläche. Das ist nicht gut. Verwenden Sie stattdessen eine Variation des MVP-Musters, um die Präsentationslogik von den Ansichten zu entkoppeln. Ihre "Verbindungsthreads" sprechen also mit einem Intermediär, die Moderatoren sprechen mit demselben Intermediär und geben nur einige Daten zur Ansicht aus.

Bei Cross-Thread-Operationen, insbesondere bei UI-Thread-Operationen, finde ich SynchronizationContext sehr nützlich in cikrumstances, wenn Sie einen Anruf von einem Nicht-UI-Thread zum UI-Thread marshallen möchten. Eine ausführlichere Diskussion finden Sie unter this article.

Verwandte Themen