Autor |
Beitrag |
c_sharp
Hält's aus hier
Beiträge: 10
|
Verfasst: Mi 24.09.14 11:27
Hallo,
ich versuche gerade Werte einer SPS in einem Oszilloskop darzustellen. Und zwar stelle ich in bis 4 Forms je ein Chart mit 3 Kurven dar.
Wenn ich jedoch 4 Forms gleichzeitig offen habe, friert die Oberfläche ein.
Eine Messung hat gezeigt, dass ein Programmzyklus ca. 20µs pro Form braucht.
Ist das schon zu langsam? Oder muss ich etwas spezielles beachten,wenn ich mehere Forms gleichzeitg betreiben will.
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mi 24.09.14 11:43
Multiple Formen sind kein Problem. Das was auf der Form ist und das was du auf der Form machst könnte ein Problem sein. Ungesehen ist da wenig zu sagen.
Ich könnte jetzt nur vermuten das dein Verfahren zum holen der Daten und verteilen auf die Charts die Ursache ist oder
eventuell noch die Art wie du das aktualisieren der Charts anstößt (Timer gebastel etc.).
|
|
c_sharp 
Hält's aus hier
Beiträge: 10
|
Verfasst: Mi 24.09.14 11:48
Hallo, danke für die schnelle Antwort.
An der Datenübertragung liegt es nicht.
In dem Form habe ich ein Chart von Steema. Über einen Timer starte ich einmal pro Sekunde einen BackroundWorker, in welchem ich das Chart neu zeichne.
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mi 24.09.14 11:59
Zitat: | Über einen Timer starte ich einmal pro Sekunde einen BackroundWorker, in welchem ich das Chart neu zeichne. |
Da du aus einem anderen Thread nicht einfach Controls aktualisieren darfst wirst du im BackgroundWorker irgendwie den Zugriff auf die UI synchronisieren.
Das solltest du dir genau ansehen wie du das machst und ob du dir da zum Beispiel eine Art Deadlock gebaut hast.
|
|
Th69
      

Beiträge: 4799
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Mi 24.09.14 11:59
Hallo,
c_sharp hat folgendes geschrieben: | Über einen Timer starte ich einmal pro Sekunde einen BackgroundWorker, in welchem ich das Chart neu zeichne. |
Das ergibt aber überhaupt keinen Sinn 
|
|
c_sharp 
Hält's aus hier
Beiträge: 10
|
Verfasst: Mi 24.09.14 12:21
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mi 24.09.14 12:29
Das sieht nicht nach Timer aus sondern nach einer StopWatch
Deine Aussage ist merkwürdig weil
a.) nur der Hauptthread zeichnen kann und in einem anderen Thread maximal die Daten zusammengesucht werden können um sie dann an den Hauptthread zu geben damit der zeichnet
b.) die Kombination aus Timer (womöglich mit einem Thread) und BackgroundWorker (ein Thread) ziemlich überflüssig scheint. Entweder man nimmt einen Threaded Timer und erledigt die Aufgabe im Timer event oder man nimmt einen Thread (zum Beispiel einem Backgroundworker) und läßt ihn rotieren (Schleife die das Timing prüft) und regelmäßig was ausführen.
|
|
C#
      
Beiträge: 561
Erhaltene Danke: 65
Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
|
Verfasst: Mi 24.09.14 12:29
Was führt der Worker denn aus? Dieser Codeteil wäre interessant.
Falls du eine Stopwatch benutzt, kannst du übrigens auch watch.Restart() schreiben.
PS:
Bei Code bitte Code-Tags verwenden:
Quelltext 1: 2:
| [cs]C# Code hier rein. Geht auch über mehrere Zeilen.[/cs] |
_________________ Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
|
|
c_sharp 
Hält's aus hier
Beiträge: 10
|
Verfasst: Mi 24.09.14 12:37
Ja ist eine Stopwatch.
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| public void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { backgroundWorker1.WorkerReportsProgress = true; backgroundWorker1.ReportProgress(1); } private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { if (this.fastLineSeries1.Count > Convert.ToInt32(AnzeigeWerte) ) this.fastLineSeries1.Delete(0, this.fastLineSeries1.Count - Convert.ToInt32(AnzeigeWerte)); if (this.fastLineSeries2.Count > Convert.ToInt32(AnzeigeWerte) ) this.fastLineSeries2.Delete(0, this.fastLineSeries2.Count - Convert.ToInt32(AnzeigeWerte)); if (this.fastLineSeries3.Count > Convert.ToInt32(AnzeigeWerte) ) this.fastLineSeries3.Delete(0, this.fastLineSeries3.Count - Convert.ToInt32(AnzeigeWerte));
tChart1.AutoRepaint = true; fastLineSeries1.Repaint(); fastLineSeries2.Repaint(); fastLineSeries3.Repaint(); tChart1.AutoRepaint = false; } |
Ich hab gelesen,dass Zugriffe auf Grafikelemente in backgroundWorker1_ProgressChanged gemacht werden sollen.
|
|
Th69
      

Beiträge: 4799
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Mi 24.09.14 12:41
Der BackgroundWorker ist doch bei deinem Code überflüssig, da du keine langlaufende Aktion tätigst.
Dann kannst du gleich den im ProgressChanged-Ereignis stehenden Code direkt (im GUI-Thread) ausführen.
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mi 24.09.14 12:41
Denn BackgroundWorker kannst du dir sparen.
Die ~Hintergrund~ Aufgabe gehört in den DoWork Event in dem du aber nichts tust.
ProgressChanged ist bereits wieder synchronisiert in den Hauptthread. Dann kannst du es auch gleich im Hauptthread machen.
|
|
C#
      
Beiträge: 561
Erhaltene Danke: 65
Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
|
Verfasst: Mi 24.09.14 12:45
Also nimm dafür am besten einen WinForms-Timer (der ist schon mit der UI synchronisiert), der im Sekundentakt tickt:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| Timer timer;
void Setup() { timer = new Timer { Interval = 1000 }; timer.Tick += TimerTick; timer.Start(); }
void TimerTick(object sender, EventArgs e) { int wert = int.Parse(AnzeigeWerte); if (fastLineSeries1.Count > wert) fastLineSeries1.Delete(0, fastLineSeries1.Count - wert); if (fastLineSeries2.Count > wert) fastLineSeries2.Delete(0, fastLineSeries2.Count - wert); if (fastLineSeries3.Count > wert) fastLineSeries3.Delete(0, fastLineSeries3.Count - wert);
tChart1.AutoRepaint = true; fastLineSeries1.Repaint(); fastLineSeries2.Repaint(); fastLineSeries3.Repaint(); tChart1.AutoRepaint = false; } |
_________________ Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
Für diesen Beitrag haben gedankt: c_sharp
|
|
c_sharp 
Hält's aus hier
Beiträge: 10
|
Verfasst: Mi 24.09.14 12:58
Vielen Dank C#.
So funtioniert es.
Ich habe bei dem BackgroundWorker irgendetwas falsch verstanden, dass muss ich mir nochmal genauer anschauen.
|
|
C#
      
Beiträge: 561
Erhaltene Danke: 65
Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
|
Verfasst: Mi 24.09.14 13:20
Hat das das Performance-Problem gelöst? Kann doch nicht daran gelegen haben 
_________________ Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
|
|
c_sharp 
Hält's aus hier
Beiträge: 10
|
Verfasst: Mi 24.09.14 13:30
Hab mich wohl zu früh gefreut...
Wenn in allen 4 Forms viele Daten dargestellt werden (insgesamt ca. 300.000 Werte) ruckelt die Oberfläche immer noch
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mi 24.09.14 13:38
In was für einem Charttyp kann man denn unterscheidbar 300000 Werte anzeigen?
|
|
c_sharp 
Hält's aus hier
Beiträge: 10
|
Verfasst: Mi 24.09.14 13:41
Das ist ein Teechart von der Firma Steema
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mi 24.09.14 13:45
Ok. Aber wie kann es gleichzeitig 300000 Werte darstellen? Bei zum Beispiel einem LineChart macht es wenig Sinn mehr Werte anzuzeigen als die verfügbare Breite in Pixel.
Wenn du das Chartcontrol auf dem gesamten Datenbestand rumkauen lässt würde mich nicht wundern wenn es einfach überfordert ist (mit vorraussichtlich überflüssigen Berechnungen) und daher langsam.
|
|
C#
      
Beiträge: 561
Erhaltene Danke: 65
Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
|
Verfasst: Mi 24.09.14 13:45
Das war wohl eher Ironie von Ralf. Du kannst in keinem Chart 300.000 Werte anzeigen. Wer soll die denn auswerten bzw. ablesen? Nur weil du 300.000 Datensätze hast, musst du die doch nicht alle anzeigen. Das ist nämlich ein Performancefresser.
Rechne die Daten lieber auf Mittelwerte runter.
Sagen wir du willst 300 Werte anzeigen, dann nimmst du immer 1000 Werte und berechnest den Durchschnitt daraus. Und diese Durchschnittswerte übergibst du dann deinem Chart.
/// Nachtrag
Verdammt. Schon wieder zu langsam  .
Stell dir mal vor du musst eine 0.1mm lange Linie zeichnen mit einem Stift, dessen Miene 2mm dick ist. Dann weißt du wie sie die Graphics-Einheit der Chart fühlt 
_________________ Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
|
|
c_sharp 
Hält's aus hier
Beiträge: 10
|
Verfasst: Mi 24.09.14 13:52
Ich will aber die Werte der SPS anzeigen (z.B. Soll und Istposition). Wenn ich jetzt Werte weg lasse oder den Mittelwert berechne habe ch ja nichts gewonnen, da ich zum Bsp. Picks übersehe.
Und ja es sind viele Werte. Im Moment sind es 12 Variablen, die Zykluszeit des SPS ist 200µs und die Anzeigezeit pro Chart liegt irgendwo bei 30-50 sec.
|
|