Laden...

Architektur-Frage für Daten-Sammler

Erstellt von wondermike vor 8 Jahren Letzter Beitrag vor 8 Jahren 1.114 Views
W
wondermike Themenstarter:in
2 Beiträge seit 2016
vor 8 Jahren
Architektur-Frage für Daten-Sammler

Hallo, ich möchte eine Anwendung schreiben, die folgende Dinge macht:*Empfangen von Messdaten über verschiedene Named Pipes *Speichern der Messdaten in eine Datenstruktur (pro Pipe separat, aber schon alles zusammen) *In Echtzeit anhand der empfangenen Daten entscheiden, ob Daten aus einer Pipe anders sind als Daten aus anderen Pipes (ich nenne die Logik mal EntscheiderKlasse) *Auf WPF-GUI Status anzeigen

Das ist gleich ein ganzer Korb voller Technologien, die da beteiligt sind. Ich habe bereits einige Versuche gemacht und bin dabei auf Schwierigkeiten gestoßen. Statt Euch mit 1000en Zeilen Code zu quälen, möchte ich nochmal ganz vorne anfangen, aber gleich gezielt auf die neuralgischen Punkte kommen, die dann in Fragen münden werden.

Ich habe mit diesem Beispiel angefangen: http://www.codeproject.com/Articles/7176/Inter-Process-Communication-in-NET-Using-Named-Pip und habe es in eine WPF-Applikation integriert. Erste Frage, die dabei auftauchte: Wie kann ich die Datenstruktur (DS) anlegen und wie kann ich diese den Threads zugänglich machen, so dass die darin schreiben können? Ich habe eine Klasse für die DS erstellt (members: 1 string und 2 doubles) und habe versucht, diese irgendwie zu übergeben oder gar global zugänglich zu machen, doch dafür fehlten mir leider die Grundlagen. Als Datentyp würde eigentlich eine Queue ausreichen, weil immer nur die letzten x Messwerte relevant sind (z.B. 5). Längerfristige Betrachtungen möchte ich nicht anstellen. Ich habe demzufolge auch mit einer ConcurrentQueue experimentiert; ich konnte zwar dort rein schreiben, doch der Consumer-Thread hat da nicht reagiert, und ist beim Monitor.Wait() hängen geblieben, wahrscheinlich weil es nicht auf die DS zugegriffen hatte, sondern nur auf etwas mit gleichem Namen.

Eine andere Problematik war dann, dass ich keine GUI-Elemente aktualisieren konnte, weil ich nicht im WPF-Thread war. Die Frage, welche mir Google nicht beantworten konnte: WO muss ich die Delegate, welche das via Dispatcher erledigt, genau unterbringen?

Dann beschäftigte mich die Frage: Wie lasse ich die EntschiederKlasse auf die DS zugreifen und wie vor allem lasse ich diese Laufen? Am liebsten wäre mit ein Thread, der im Hintergrund läuft.

Ich hoffe, ich war konkret genug, so dass Ihr mir ein paar Tipps geben könnt.
Vielen Dank im Voraus & Schönen Gruß
wondermike

16.841 Beiträge seit 2008
vor 8 Jahren

Naja. Du hast hier einen Codeproject Artikel aus 2004 ausgekramt und diesen integriert.
Glaubst Du wirklich, dass ein 12 Jahre alter Artikel in der sehr schnell lebigen Welt der Software noch nicht technisch überholt ist? =)
Um die Frage zu beantworten: das ist er mit Sicherheit. 🙂

Was Du mit der Datenstruktur aussagen willst; keine Ahnung.

Eine Thread-sichere Queue zu bauen, die nur X Einträge behält, ist trivial:

public class FixedSizedQueue<T>
{
     public FixedSizedQueue(int limit)
     {
         Limit = limit;
     }
     
     private ConcurrentQueue<T> _queue = new ConcurrentQueue<T>();

     private volatile int _limit;
     public int Limit
     {
        get { return _limit; }
        set { _limit = value; }
     }
     
     private object _lockMe = new object();
     
     public void Enqueue(T obj)
     {
        _queue.Enqueue(obj);
        lock (_lockMe)
        {
           T overflow;
           while (_queue.Count > Limit && _queue.TryDequeue(out overflow)) ;
        }
     }
}

Mir scheint, dass Du auch noch ein wenig die Struktur des Projekts misslingt.
Du solltest die Logik vollständig von der GUI entkoppeln.
[Artikel] Drei-Schichten-Architektur

Bei WPF verwendet man zudem MVVM. Das ist mehr als nur eine Empfehlung!
Ohne MVVM kommst Du bei WPF nicht weit.
[FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke)

W
872 Beiträge seit 2005
vor 8 Jahren

MVVM ist der Startblock.
Kern von MVVM ist INotifyChangeProperty, was dann automatisch die Synchronisation zwischen dem GUI Thread und der jeweiligen Datenstruktur vornimmt.

Statt Delegates würde ich Reactive Extensions benutzen. Neben der Entkoppelung von Delegates bekommst Du vor allem die Events als Stream plus Error und Completed und vielen LINQ mässigen Möglichkeiten zum Filtern.

Wenn Du Dir Beispiel anschauen willst, dann würde ich Dir Reactive Trader und Dynamic Trader empfehlen.

Dafür braucht es aber eine ganze Menge Frust-Toleranz, da das zwar sehr gute Beispiele sind, aber die Einstiegshöhe sehr hoch ist.

W
wondermike Themenstarter:in
2 Beiträge seit 2016
vor 8 Jahren

Hallo, Danke erst mal für die Antworten - meine Anforderung war zwar etwas prozedural verfasst, mein Prototyp hat allerdings sehr wohl schon vor meinem Posting eine 3-Schichten und MVVM implementiert. Ich habe halt versucht, den Code von "damals" da zu integrieren. Vielleicht habe ich mich da falsch ausgedrückt.

Ich habe allerdings mittlerweile ein sehr brauchbares Grundgerüst für meine Applikation gefunden, welches so etwas quasi schon vereint:
http://dotnet-experience.blogspot.de/2012/02/inter-process-duplex-communication-with.html

Die Applikation ist genial und genial einfach und lässt sich leicht auf meine Bedürfnisse anpassen. Da kann ich erst mal drauf aufbauen. Dort die Queue unterbringen und die GUI aktualisieren bzw. auch meine bisher entwickelte GUI rüber verfrachten.

Jo, ich glaub ich hab jetzt den Schuhlöffel.

Das ist ist wie mit Cobol ... ich möchte gerne mal DEN kennenlernen, der das erste Cobolprogramm geschrieben hat(, von dem dann alle ihre Programme kopiert haben). 😉

Den ReactiveTrader/DynamicTrader werde ich mir allerdings auch mal anschauen, weil ich nämlich in einem anderen/späteren Projekt auch den MT4 mit Pipes anzapfen wollte.

Danke nochmal