Entwickler-Ecke
Basistechnologien - Thread Kommunikation
Soc - So 29.11.09 15:21
Titel: Thread Kommunikation
Hallo Zusammen,
ich habe einen Windows Dienst erstellt, der wiederum mehrere Worker Threads aufbaut.
Jeder dieser Threads hat eine bestimmte Aufgabe zu erledigen. Er soll durch ein Command "geweckt" werden, diesen dann ausführen, ein Ergebnis zurück liefer und anschliessend wieder schlafen.
Sollte man das über einen Event steuern ? Und wenn ja, wie geht die Kommunikation ?
Gruß
Soc
Kha - So 29.11.09 18:41
Solange wir nicht wissen, was für ein Command das sein soll, wo es her kommen soll und wohin das Ergebnis geliefert werden soll, lässt sich leider nicht viel über mögliche Kommunikationswege aussagen.
Soc - Mo 30.11.09 10:37
Kha hat folgendes geschrieben : |
| Solange wir nicht wissen, was für ein Command das sein soll, wo es her kommen soll und wohin das Ergebnis geliefert werden soll, lässt sich leider nicht viel über mögliche Kommunikationswege aussagen. |
Hallo Kha,
Der Dienst startet wie gesagt alle Worker Threads.
Diese erledigen Initialisierungsarbeiten und warten dann auf einen Funktionesaufruf.
Als Beispiel dient hier ein Thread, welcher alle Registry Zugriffe übernimmt. Er bekommt z.B. ein Command "Refesh". Damit soll er bestimmte Registry Werte auslesen und neu in eine Liste stellen.
Der Dienst soll dann nach erfolgreicher Arbeit ein "True" oder "false" zurück bekommen.
Bei "false" sollte der Dienst auch eine Fehlermeldung einsehen können, welche er dann dem Message-Thread (dieser kümmert sich um den gesamten Log) zur weiteren Verarbeitung übergibt.
Gruß
Soc
Kha - Mo 30.11.09 19:23
Zumindest bei diesem Beispiel ist ein durchlaufender Nebenthread, der auf Nachrichten wartet, imo fehl am Platze. Starte bei einem "Refresh"-Command doch einfach einen neuen Thread für diese Aufgabe, genau dazu ist der Threadpool da.
Auch denke ich, dass dieser Thread dann gleich sein eigenes Logging übernehmen könnte. Synchronisierung mit anderen Threads scheint mir (bis jetzt) eigentlich nur bei GUI-Anwendungen sinnvoll, weil es dort nötig ist.
Soc - Di 01.12.09 09:14
Kha hat folgendes geschrieben : |
Zumindest bei diesem Beispiel ist ein durchlaufender Nebenthread, der auf Nachrichten wartet, imo fehl am Platze. Starte bei einem "Refresh"-Command doch einfach einen neuen Thread für diese Aufgabe, genau dazu ist der Threadpool da.
|
Mh, trotzdem bleibt dann die Frage auf, wie ich einen Response vom Thread zurück bekomme.
Gruß
Soc
Kha - Mi 02.12.09 11:50
Ein Threadwechsel ist eigentlich nur möglich, indem der eine Thread auf den anderen wartet (was er natürlich auch periodisch machen kann). Deshalb meine Frage: Wozu? Wieso alle zusammenhängenden Arbeitsschritte im gleichen Thread ausführen?
Soc - Mo 14.12.09 15:44
Kha hat folgendes geschrieben : |
| Ein Threadwechsel ist eigentlich nur möglich, indem der eine Thread auf den anderen wartet (was er natürlich auch periodisch machen kann). Deshalb meine Frage: Wozu? Wieso alle zusammenhängenden Arbeitsschritte im gleichen Thread ausführen? |
Hallo Kha,
nun, sicherlich könnte ich alle Aufgaben in einen Thread durchführen, würde aber den Thread extrem aufbläahen und hilft bei der Übersicht nicht besonders.
Deshalb habe ich mit überlegt einzelnen Funktionen in einzelnen Threads auszulagern.
Und dabei kommt nun die Frage hoch wie ich eine Kommunikation der einzelnen Threads hin bekomme.
Gruß
Soc
Kha - Mo 14.12.09 19:30
Soc hat folgendes geschrieben : |
| nun, sicherlich könnte ich alle Aufgaben in einen Thread durchführen, würde aber den Thread extrem aufbläahen und hilft bei der Übersicht nicht besonders. |
Huch? Wenn die Entscheidung, welche Methode in welchem Thread laufen soll, dein Design beeinflusst, hast du imho etwas falsch gemacht :gruebel: . Jeder andere Ansatz kann in puncto Threading jedenfalls nur wesentlich komplizierter werden.
Es gibt sicherlich Probleme, bei denen "Ein Thread pro Schritt" Sinn macht, bin nur nicht überzeugt, dass das bei dir zutrifft ;) . Die Lösung für solche Fälle heißt
BlockingCollection<T> [
http://msdn.microsoft.com/en-us/library/dd267312%28VS.100%29.aspx] - jedenfalls ab .NET 4.0 :mrgreen: . In
diesem Paper [
http://blogs.msdn.com/pfxteam/archive/2009/11/09/9919848.aspx] (das insgesamt nur zu empfehlen ist :D ) findest du auf Seite 52 eine Implementierung einer ähnlichen Klasse:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| class BlockingQueue<T> { private Queue<T> _queue = new Queue<T>(); private Semaphore _semaphore = new Semaphore(0, int.MaxValue); public void Enqueue(T data) { if (data == null) throw new ArgumentNullException("data"); lock (_queue) _queue.Enqueue(data); _semaphore.Release(); }
public T Dequeue() { _semaphore.Wait(); lock (_queue) return _queue.Dequeue(); } } |
Die kannst du als Basis für ein Producer/Consumer-Schema benutzen: Ein Thread schiebt per Enqueue Daten an den nächsten, der durch Dequeue am anderen Ende darauf wartet.
Soc - Di 15.12.09 13:39
Hallo Kha,
danke für den super Tip.
Sicherlich ist es nicht optimal solche Aufteilung in Threads aufzunehmen, aber ein Thread mit allen Funktionen würde sehr unübersichtlich werden.
Trotzdem Danke für die Warnung. Ich werde mir Deine "Lösung" mal anschauen und nochmals über mein Design nachdenken (müßen).
Gruß
Soc
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!