3 Fragen: 1:zu strict on 2:Array und große Datenmengen 3: Multithreading

  • VB.NET

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von Eggord.

    3 Fragen: 1:zu strict on 2:Array und große Datenmengen 3: Multithreading

    Hey ich habe mal wieder ein paar fragen ^^

    1.:ich habe mal strict on eingestellt dabei habe ich bemerkt das bei der variable j as short j +=1 nicht funktioniert. ich muss CShort(j+1) schreiben. Ist das normal? gibt es da eine lösung für short?

    2.: Ich muss eine menge Daten speichern. Ich wollte das eigentlich in einem Multidim. Array(pro Kanal eine Spalte) machen. allerdings werde ich dafür das Arry immer wieder neu skallieren müssen bevor ich die daten reinpacke. Gibt es eine bessere oder einfache Methode als Arrays? Wieviel speicher wird dieses Array den benötigen. ich nehme 8000 Werte pro Sekunde pro Kanal auf. Max sind es 5 Kanäle -> macht also eine Datenmenge von 40kHz. Die Zeit der aufnahme ist unterschiedlich. kann aber locker 30 min sein -> 40k*60*30 =72.000.000 Daten Gibt es irgendwas mit dem man das effizient speichern kann und damit auch arbeiten kann?

    3.:Ich habe einen EventHandler, von dem ich die Daten der Kanäle in Pakten(Buffer) bekomme. Nachdem ich diesen Buffer geleert habe muss der wieder an die Datenerfassungskarte geschickt werden. Ein Paket soll die Daten für ca. 0.5 sekunden beinhalten. In dem Handler wollte ich dann durch Aufrufen anderer Subs die Daten bearbeiten. Dazu muss man sagen, dass der Handler an sich schon in einem anderen Thread wie die Form ist.Ich bin mir nicht sicher ob die berechnungen innerhalb einer halben sekunde erledigt sind wollte aber das der Buffer dann schon wieder bei der Karte ist.
    Der Befehl den Buffer an die Karte zu schicken kommt nach den Aufruf der Berechnungen. Wartet das Programm nun bis die Berechnungen zuende sind bevor es den Buffer wieder an die Karte schickt oder nicht. Bringt es irgendwas wenn ich die berechnungen in einem eigenen thread durchführen lasse?

    Ist ne Menge Text geworden...sorry

    Danke schonmal im vorraus!!
    1: Das ist normal und lässt sich einfach umgehen: verwende Integer. Das Ergebnis von Short + 1 ist ein Integer. Da Strict ON ist musst du diesen convertieren.
    Ich war dumm xD

    VB.NET-Quellcode

    1. Dim a As Short = 0
    2. a += 1S

    durch anhängen eines "S" kennzeichnest du die Zahl als Short.

    2: Eine ListOf sollte damit keine Probleme haben. Mit .Add kannst du einfach Werte hinzufügen.
    Ich würde aber die Werte in Blöcke unterteilen (kp, 1000 Werte = 1 Block) und auf die Platte schreiben. So kannst du riesen-Dateien einfach per FileStream auslesen sofern jeder Werte eine fixe Byte-Länge in der Datei hat. Oder Du musst die Positionen der Blöcke speichern, dann kannst du sie wenigstens Blockweise auslesen. Ist arbeit, würde sich bei extrem vielen Werten aber lohnen nicht alles im Arbeitsspeicher zu halten.


    3: Das verstehe ich nicht so ganz. Du zeichnest Daten auf und bearbeitest sie Blockweise. Das Aufzeichnen hat somit eine Höhere Priorität als das bearbeiten - logisch, denn nur Daten die aufgezeichnet wurden können auch bearbeitet werden^^
    Ich würde es also so machen, dass Aufgezeichnet wird, dann wird der Block auf eine Warteliste gesetzt und nach dem FIFO-Verfahren bearbeitet. So hinkt das Bearbeiten evtl etwas nach, es wird aber nie zu dem fatalen Problem kommen, dass die Datenerfassung (die ja u.U. nur einmalig möglich ist) ausgelassen wird. In dem Fall musst du in zwei Threads arbeiten: Aufzeichnen, Bearbeiten. Unter .NET 4.0 kannst du übrigens alle Prozessorkerne auslasten (Parallel.For) was ein enormes Geschwindigkeitsbonus bringen kann.

    Zu deiner Frage: Ja, das Programm wartet bis die Berechnungen fertig sind - erst dann wird der Buffer wieder an die Karte geschickt (kp was das bedeutet xD). Threads würden das beheben, lese dich am besten etwas ins Thema Asynchrones Programmieren ein.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „FreakJNS“ ()

    Wow ich hätte nicht gedacht heute nacht noch eine ANtwort zubekommen. Danke!

    Frage 1 gelöst!

    Frage 2: Das zwischenspeichern ist eine gute Idee. ich brauche nämlich eigentlich nicht das gesamte array sondern lediglich die letzten 30 sek. dann könnte ich eigentlich auch wieder mit array arbeiten. Ich schaue mir aber Listof trotzdem mal an. Gibt es die multidimensional? Das mit den Blöcken verstehe ich noch nicht so ganz. kann ich die daten nicht einfach zeile für zeile in die datei schreiben? auch wenn die schon besteht?

    Frage 3: Du hast das schon richtig verstanden. Ich habe es nur kompliziert geschrieben. Dann muss ich mich dieses WE doch mit dem Multithreading auseinandersetzten :wacko: ;( (vll kommen da noch ein paar threads von mir ^^ ). Bei dem FIFO könnte man wieder gut ListOf verwenden, da die größe ja sehr leicht stark schwanken kann.

    Da ich in dem bearbeitungs thread auf das form zugreifen muss, um die daten zu plotten. macht es nicht dann sinn die berechnung auch in diesem thread zu machen? Oder würde mir das dann meine komplette GUI lahmlegen?
    Finde das ganze hier recht Interessant, von daher kannst du auf meine "Mitarbeit" zählen! xD

    2: Das Problem wenn du Zeile für Zeile in die Datei schreibst ist, dass es recht langsam ist (das weiß ich nur vom hörensagen, kann auch sein, dass es garnicht stimmt). Desswegen würde ich die Daten in Blöcken zusammenfassen, z.B. zu 1000 Datensätzen. Ein Datensatz enthält demnach die Werte von 5 Kanälen. So muss nur 8 mal pro Sekunde geschrieben - ist immernoch sehr viel aber nichts im vergleich zu 8000 Schreibvorgängen. Ein Stream sollte damit zurecht kommen und optimieren kann man ja später immernoch.

    Aber davor würde ich mir Gedanken über einen Datensatz machen.Statt vielen kleinen Arrays die sich dann in einer ListOf wiederfinden würde sich hier eine Structur wohl am besten eignen. Structuren sind im Gegensatz zu Klassen Wertetypen und werden soweit ich weiß schneller bearbeitet. Ich nehme mal an, dass jeder Wert eine Variable vom Typ Short ist, also würde die Structur "Datensatz" entweder 5 einzelne Short-Variablen enthalten oder einen Array mit 5 Shorts. Was sich da besser eignet musst du wissen..

    Wenn alles richtig angestellt wurde, dann braucht ein Datensatz genau 10 Byte (5Kanäle * 2Byte pro Short). Das ist einwandfrei, so kannst du gezielt einzelne Werte bzw Blöcke aus der Datei auslesen, da du die Position der Daten berechnen kannst. Auch hier wird wieder mit einem Stream ausgelesen. So wird nur das nötigste im Arbeitsspeicher sein.


    3: Für eine FIFO könnte man eine ListOf benutzen. Allerdings bietet das .NET-Framework etwas viel besseres: die QueueOf. Viel besser als selbst etwas zu basteln^^

    Bei deinen letzen beiden Fragen kann ich keine wirkliche Antwort geben, da ich nicht weiß
    - Was für Daten sind das eigentlich genau und wo kommen sie her? (vermutlich Audiodaten?)
    - Was passiert mit ihnen?
    - Was bedeutet "plotten"?
    - Was sollte ich noch wissen?^^
    - Warum musst du im bearbeitungs-Thread auf die Form zugreifen?

    Prinzipiell solltest du während dem Berechnen garnicht auf die Form zugreifen müssen, vor allem hier sollte eine strikte Trennung von Benutzeroberfläche, Daten und Berechnungen gemacht werden. Am besten eine art Arbeiter-Klasse schreiben, die alle nötigen Funktionen bereitstellt (aufzeichnen, bearbeiten, speichern, etc). Diverse Eigenschaften beinflussen die Arbeitsweise der Klasse. Verändert werden diese Eigenschaften vom Benutzerinterface - also deiner Form. So hat man aber eine Trennung von beidem.

    Da das bearbeiten ja scheinbar recht Zeitaufwändig ist würde ich es in einem Thread auslagern - noch besser in einem Backgroundworker. Da hast du den Vorteil, dass er seinen Status melden kann. Eine Statusmeldung kann alle möglichen Informationen aus dem Thread herausführen - zunächst innerhalb der Arbeiter-Klasse und dann per Events auch nach ganz außen, damit der User etwas auf der Form zu sehen bekommt. So sollte das Bearbeiten reibungslos funktionieren.

    Ähnliches kann man - in einem weiterem BGW -mit dem Einlesen machen, Daten sammeln, dann ein Block der FIFO-Liste hinzufügen, weitersammeln. Der Bearbeiter-BGW arbeitet die FIFO ab wenn sich etwas auf ihr befindet.

    So ist ein blockieren der GUI ausgeschlossen, dein Form-Code bleibt übersichtlich, du kannst den Code wiederverwenden für ein weiteres Projekt und du kannst viele Vorteile vom Klassen-Programmieren für dich nutzen.


    So, genug geschrieben für Nacht^^ Finde das aber wirklich sehr interessant und es ist mal eine Abwechslung.
    Wäre nett wenn du mir genau erklärst was wie und wo da passiert und passieren soll. Sind es Audio-Daten? Wo kommen die her? Wie willst du sie bearbeiten? Warum brauchst du nur die letzten 30 Sekunden? Was muss gespeichert werden - Die Rohdaten oder die Bearbeiteten? Willst du das ganze grafisch darstellen - plotten hört sich so danach an? Und und und^^ Ruhig ausführlich werden - oder Bilder anhängen wenn möglich.

    lg!

    Eggord schrieb:

    allerdings werde ich dafür das Arry immer wieder neu skallieren müssen bevor ich die daten reinpacke.
    wenn du mit "skalieren" meinst, dass du die Array-Größe verändern willst, dann lass die Finger von Array.
    Nimm mindestens List(Of T), vlt. auch Queue(Of T), oder in Threading-Szenarien u.U. BlockingCollection(Of T) oder sonstwas anneres als Array.
    Die .Net-Auflistungsklassen wrappern im Grunde auch nur ein Array, aber verwenden einen sehr genialen Algo zur "Skalierung", also Größenanpassung.
    Ein mehrdimensionales Array ist zusätzlich zur Unflexiblität auch besonders unfreundlich zum Arbeitsspeicher, denn es belegt einen einzigen fetten Speicherblock.

    Die direkte Alternative heißt "Jagged Array", und meint, statt eines mehrdimensionalen Arrays nimmt man ein Array von Arrays. Da ein Array von Arrays aus vielen kleinen Arrays besteht, können die im Arbeitsspeicher wesentlich besser verwaltet werden.
    Aber da du eh Auflistungen verwenden solltest, wirst du eh bei "jagged Auflistungen" rauskommen, denn Mehrdimensionalität im Sinne von wie im Array gibts bei Auflistungen garnet.
    @ErfinderDesRades

    Ich habe mal wieder einen meiner berühmten Stopwatch-Tests gemacht:

    Die Kandidaten sind einmal eine Structure sowie Class:

    VB.NET-Quellcode

    1. Class/Structure Datensatz
    2. Public w1 As Short
    3. Public w2 As Short
    4. Public w3 As Short
    5. Public w4 As Short
    6. Public w5 As Short
    7. End Structure

    und ein normales Short-Array mit einer Länge von 5 (0 to 4) => "JaggedArray"

    Das komplette durchlaufen von 1.000.000 solcher datensätze + ein paar aditionsrechnungen dauert:

    als List(Of DatensatzStruct): 21ms
    als List(Of DatensatzClass :( 27ms
    als List(Of Short()): 46ms


    Wie ich vermute habe ist also eine List(of DatensatzStructure) am günstigsten. Man muss nur immer bedenken, dass es sich um einen Wertetyp handelt - sollte bei dieser Art der Daten aber nicht alt zu schwer sein. Vor- und Nachteile gegenüber dem Array sollte es nicht geben, da man sich ja ganz leicht eine Property in die Structur/Class bauen kann, die einen Wert per Index ausliest bzw setzt. Schon funst es wie ein Array:

    VB.NET-Quellcode

    1. Structure Ds
    2. Public w1 As Short
    3. Public w2 As Short
    4. Public w3 As Short
    5. Public w4 As Short
    6. Public w5 As Short
    7. Default Public Property GetSetValue(ByVal i As Integer) As Short
    8. Get
    9. Select Case i
    10. Case 0
    11. Return w1
    12. Case 1
    13. Return w2
    14. Case 2
    15. Return w3
    16. Case 3
    17. Return w4
    18. Case 4
    19. Return w5
    20. Case Else
    21. Throw New Exception("Ungültiger Index!")
    22. End Select
    23. End Get
    24. Set(ByVal value As Short)
    25. Select Case i
    26. Case 0
    27. w1 = value
    28. Case 1
    29. w2 = value
    30. Case 2
    31. w3 = value
    32. Case 3
    33. w4 = value
    34. Case 4
    35. w5 = value
    36. Case Else
    37. Throw New Exception("Ungültiger Index!")
    38. End Select
    39. End Set
    40. End Property
    41. End Structure


    VB.NET-Quellcode

    1. Dim tmp As Ds 'Kein New, da Structur
    2. Dim wert As Short = tmp(2) 'da default Property: direkter zugriff auf einen pseudo-array


    Ich denke, dass sich so etwas halbwegs performantes programmieren lässt, dass zudem auch noch mit der großen datenmenge zurechtkommt.
    (Also StopWatch ist in sonem Kurzzeit-Bereich (<50ms) nicht sonderlich genau.)
    IMO hast du v.a. gezeigt, dasses vonne Geschwindigkeit her total schnuppe ist: 47ms für 1 Mio Durchläufe ist ein vielfaches von mehr als ausreichend schnell.

    Und 27ms sind dann eben das doppelte vom vielfachen von mehr als ausreichend schnell - das bringt dann auch keinem mehr was
    Weil man rennt ja nicht nurso 1 mio items durch, sondern man verarbeitet die irgendwie, und diese Verarbeitung dürfte normalerweise 100-fach, 1000-fach oder auch 10000-fach langsamer sein. Also selbst wenn sie nur 100-fach langsamer ist, so wird dadurch der Unterschied ob nu List(Of datenStruct) oder List(Of datenItem()) vollkommen belanglos, denn an der Stelle kann man logisch grade mal 0,5% Geschwindigkeit rausholen.



    Übrigens, wenn du gerne Benchmarks machst, gugge vlt. die "MyStopWatch"-Klasse aus Heap - performante sortierte Datenstruktur.

    Die funktioniert mit umgedrehter Logik: Also man gibt nicht eine Anzahl von Durchläufen an, und misst wie lange es dauert, sondern man gibt eine Laufzeit vor und zählt die Durchläufe. So misst man dann eine größere Zeitspanne. Bei sehr schnellen Sachen verfälscht natürlich das "Gucken auf die Uhr" wieder das Ergebnis, aber man kann ja jeden Ablauf in eine Schleife bis 1000 packen, damit wäre diese Verfälschung auch unter 0,1% gedrückt.
    Ach - guck dir einfach die Syntax von "MyStopWatch.Until()" an: MyStopWatch
    schön, dass ich jemanden interessieren kann :D

    Wenn ich es so durchlese könnte würde ich auch als erstes an audiodaten denken. Mit Karte ist allerdings eine Datenerfassungskarte gemeint. Diese hat mehrere Analog Ein und Ausgänge sowie Digitale Ports. Es sind also Spannungen die man misst.(Im Bereich von -10 bis 10 V mit einer Auflösug von 12-bit sind also Double keine Shorts).

    Plotten bedeutet, die Daten in einem Graphen darzustellen. Ich habe einen Graphen mit y-Achse = Spannung und x-Achse = Zeit . Auf diesem sollen aber nicht alle Daten angezeigt werden(zumindest in der Aufnahme Form nicht) sondern es ist ein laufender Graph. Deswegen reicht es wenn ich die letzten Sekunden anzeige -> deswegen auch die 30 Sekunden.

    Die Datenaufnahme von solchen Karten(solange es keine realtime karten sind, welche aber gleich 5000 Euro aufwärts kosten) funktioniert wie folgt. Man erstellt ein paar Buffer(bei mir sind es ca. 4 ) und tut die in eine Queue. Diese Buffer füllt die Karte dann. Wenn einer voll ist wird ein event ausgelöst welches ich mit einem EventHandler verarbeite. Dieses Event übergibt den vollen Buffer. Der EventHandler wird glaub ich aber in einem eigenen thread ausgeführt.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Sub HandleBufferDone(ByVal sender As Object, ByVal bufferDoneData As BufferDoneEventArgs)
    2. If Me.InvokeRequired Then
    3. Me.Invoke(New BufferDoneHandler(AddressOf HandleBufferDone), New Object() {sender, bufferDoneData})
    4. Else
    5. Dim Buffer As OlBuffer = bufferDoneData.OlBuffer
    6. If Me.chkEnablePlotting.Checked Then
    7. display1.DisableRendering()
    8. display1.SignalBufferLength = (mBuffersPlotted + 1) * mSamplesPerBuffer / display1.Signals.Count 'Diese und die nächste Zeilen bis zum Dim i .... sind für den "laufenden" Graphen
    9. display1.XDataRangeMax = (mBuffersPlotted + 1) * CInt(mSamplesPerBuffer / ainSS.Clock.Frequency)
    10. display1.XDataCurrentRangeMax = (mBuffersPlotted + 1) * CInt(mSamplesPerBuffer / ainSS.Clock.Frequency)
    11. If tbrXMin.Value > 0 Then
    12. display1.XDataCurrentRangeMin = display1.XDataCurrentRangeMax - tbrXMin.Value
    13. Else
    14. display1.XDataCurrentRangeMin = 0
    15. End If
    16. Dim i As Integer
    17. While i < display1.Signals.Count
    18. Try
    19. If Buffer.ValidSamples >= mSamplesPerBuffer Then
    20. CopyToSignal(CShort(i), Buffer) ' eigene Methode, welche die daten in den Graphen schreibt
    21. End If
    22. Catch e As Exception
    23. statusBarPanel.Text = e.Message
    24. End Try
    25. i += 1
    26. End While
    27. display1.EnableRendering()
    28. ' notify scope that new data is available
    29. display1.SignalUpdate()
    30. End If
    31. mBuffersPlotted += 1
    32. lblNumPlotted.Text = String.Format("{0} Buffers Completed", mBuffersPlotted)
    33. ainSS.BufferQueue.QueueBuffer(Buffer)
    34. End If
    35. End Sub 'HandleBufferDone


    Falls es wirklich in einem eigenen thread ausgeführt wird wieso kann ich dann eigentlich in CoppyToSignal auf die Form zugreifen?

    Eigentlich muss der Kanal, welcher auf dem Bildschirm gezeichnet wird nur je nach bedarf gemittelt werden. Sprich alle 10 Messwerte einen Mittelwert bilden und diesen dann plotten. Kann sogar sein, dass es ausreicht lediglich diese Daten abzuspeichern(würde zumindest den Speicheraufwand verringern). Alle anderen Berechnungen werden für die Analog Ausgänge benötigt. ist aber lediglich ein multiplizieren der eingangdaten oder einen Sinus oder eine gerade berechnen. Also kleinere Sachen.

    Solange sich das ganze im Bereich von unter 100 ms bewegt würde das eigentlich reichen, da ein Buffer ca. 500 ms braucht bis er voll ist. Aber man kann es natürlich auch gleich richtig machen ^^

    Wenn ich ehrlich bin habe ich das mit den Blöcken immer noch nicht verstanden. Was stellt so ein Block da? eine ListOf? Ahcja es soll auch ein auswertungsteil geben, wo aber nicht aufgenommen wird. Da bräuchte ich eigetlich die kompletten daten im Programm...Das wird auch nochmal lustig
    @ErfinderDesRades
    Okay, ich denke mal, dass man da wirklich drüber hinwegsehen kann :)
    Deine MyStopWatch habe ich mir schonmal angesehen glaubich - auch ein klasse Teil^^

    @Eggord
    Ein Double ist eine 64-Bit Zahl soweit ich weiß - 12Bit kenne ich keine, also wäre der 16Bit Lange Short der nächstbeste Datentyp.

    Mit Blocks habe ich gemeint, das mann immer nur eine Gruppe von Messwerten in die Datei schreibt. So reduziert man die Anzahl der Schreibvorgänge.

    Warum man in CoppyToSignal auf die Form zugreifen kann weiß ich nicht, ich sehe keinen Code von der Methode :)
    Vermutlich ist aber ein Backgroundworker für eine solche Aufgabe besser geeignet, da hat man mit Threadübergreifenden Vorgängen keine Probleme. Immer wenn man dem User über die Form etwas mitteilen will (z.B. Neue Werte sind da die auf ihre Darstellung auf dem Diagramm warten) lässt man den BGW einfach seinen Status melden.

    Aber was muss mit den Daten passieren? So wie ich verstanden habe müssen sie ja nur in Punkte auf dem Diagramm umgerechnet und dargestellt werden. Ich denke das sollte kein Problem sein - auch in <100ms.
    Zur Darstellung würde ich ein Control basteln, dieses fasst von mir aus tausend Werte und kann diese Darstellen. Fügt man ein neuen Wert hinzu wird der letzte aus der Liste entfernt.

    In die "Log-Datei" schreibt man eben in regelmäßigen Abständen ganze Gruppen von Messwerten. Die Datei auszulesen wird mittels Stream sehr einfach. Dem Darstellungs-Control könnte man so immer einen Abschnitt der Daten übergeben - Auswertungsteil fertig^^

    FreakJNS schrieb:

    Warum man in CoppyToSignal auf die Form zugreifen kann weiß ich nicht, ich sehe keinen Code von der Methode

    Die Methode in Post#8 invoked sich selbst - läuft also immer im MainThread. Und in zeile#27 wird dort CopyToSignal aufgerufen, was immer das bedeutet.
    Der vollständigkeitshalber:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub CopyToSignal(ByVal channel As Short, ByVal buffer As OlBuffer) 'kopiert die Daten in den Graph
    2. Dim volts As Double() = buffer.GetDataAsVolts(ainSS.ChannelList(channel))
    3. Dim lengthData As Integer = Input.Length
    4. If volts.Length = Nothing Then
    5. Dim msg As String = String.Format("IBuffer has no data")
    6. MessageBox.Show(msg, "", MessageBoxButtons.OK, MessageBoxIcon.Warning)
    7. Else
    8. Array.Resize(Input, Input.Length + volts.Length)
    9. volts.CopyTo(Input, lengthData)
    10. End If
    11. _UserControl.Display1.Signals(channel).Data = Input 'Hier werden die Daten an den Graphen übergeben. Der Graph befindet sich in einem UserControl
    12. End Sub 'CopyToSignal


    Das Control für den Graphen(Display1) habe ich bereits. Funktionioniert wunderbar ^^ Muss aber fairerweiße sagen, dass dies bei Software von dem Herrsteller der Datenerfassungskarte dabei war und ich nicht selbst geschrieben habe.

    Ich sehe übrigens gerade, dass dem Display1 nur ein Array aus Doublen übergeben werden kann. Außerdem erhalte ich meine Daten nur als Double(). 12Bit ist die Auflösung der Karte. Ob es da sinn macht die Daten zu konvertieren weiß ich nicht. Ich bin nicht so ganz sicher aber kann es nicht sein, dass dabei ungenauigkeiten entstehen? und deweiteren müsste man jeden einzelnen Wert umwandeln, was ja wieder ein "mega" rechenaufwand ist oder?

    ErfinderDesRades schrieb:

    Die Methode in Post#8 invoked sich selbst - läuft also immer im MainThread. Und in zeile#27 wird dort CopyToSignal aufgerufen, was immer das bedeutet
    ah...kann es sein, dass der Handler in einem thread der von den treibern oder klassen der Karte erzeugt ausgeführt wird und man deswegen das invoke... braucht, damit der handler im MainThread ausgeführt wird?

    Kurz zu nochmal zu den Daten: Daten die vom ersten Kanal kommen werden mit eventuell einer mittelung dem Graphen übergeben.(das ist schnell genug funktioniert übrigens jetzt schon obwohl alles mit arrays ist ^^)
    Zudem werden Die Daten benötigt um die Daten für den Ausgang zuberechnen. berechnen heißt hier invertieren und mit einem Faktor multiplizieren. Damit sollen dann die Buffer eines Ausgangs Kanals gefüllt werden. (Der anderer Ausgang gibt einfach rechteckpulse aus -> methode ist schon geschrieben, sollte schnell genug sein) Die Berechnungsmethode für den Ausgang wurde vorher in dem Handler der Datenaufnahme aufgerufen und war somit auch deren thread. Dies ist aber blöd da die Aufnahme dadurch Probleme bekommen könnte. Deswegen werde ich das jetzt den Backgroundworker erledigen lassen.

    Die Auswertung ist ein wenig komplizierter ;) Man soll am anfang die kompletten Daten in dem Graph sehen können und dann reinzoomen können(zoomen funktioniert übrigens mit dem Control super). Das ist natürlich eine unglaubliche datenmenge ich habe auch noch nicht gecheckt ob das Control überhaupt so eine datenmenge "aushällt"
    Guten Morgen^^
    Du hast wohl schon mehr vorhanden als gedacht..

    Das Umwandeln ist ja ein einmaliger Vorgang beim Erfassen der Daten - sollte zeitlich keine Probleme machen. Ist aber vllt garnicht notwendig.
    Wie kommen die Daten denn in VB.NET an? Wenn du sie als Double-Array erhältst, dann würde ich auch damit weiterarbeiten, zumal das Control einen solchen Array erfordert. Oder - was die Datenmenge reduzieren würde - du arbeitest nur mit den gemitteleten Werten weiter?

    Trifft es zu, dass du sogut wie "nur" die Verbindungen von vorhandenen Dingen herstellen muss? Das Control hast du ja, ein Einlese-System auch. Du musst nur beides irgendwie so zusammenbringen, dass das Control die letzten 30 sekunden anzeigt, die ankommenden Daten geloggt werden und die GUI nicht einfriert. Obendrauf soll dann noch die Log-Datei per Control einsehbar sein.
    Morgen ^^

    Ja einiges ist das. Das eigentliche problem was ich noch hatte oder aufkommen könnte war eigentlich das die aufnehme wegen den Berechnungen des Ausgangs in verzug kkommen könnte. Aber das geht ja mit dem Backgroundworker irgendwie.

    Du hast natürlich recht die Frima( falls es dich interessiert: DataTranslation -> kann ich nur empfehlen....solche dinger sind aber nicht ganz preiswert ;) ) bietet schon die Treiber für vb.Net und c++ an ... mit den entsprechenden klassen und allem. Man muss es halt dann noch alles konfigurieren und erstellen und soweiter. Und glücklicherweiße stellt sie halt auch das DisplayControl für vb.net zur verfügung. Das ist natürlich ein großer und wichtiger part aber ein bisschen mehr gibt es in der Form schon noch ;) . Aber man kann es schon ein bisschen verbinden von bestehenden sachen nennen :D .

    Das ich die Daten in Double-Array bekomme und weitergeben muss habe ich leider beim erstellen des Themas vergessen...SORRY...Hatte lediglich an das resize gedacht, was mich einfach tierisch nervt. Die 30 sekunden an sich sind kein problem das kann man leicht realisieren bzw ist schon realisiert ^^. Aber durch das abspeichern von blöcken kann ich zumindest den speicheraufwand im Arbeitsspeicher reduzieren. Und dass ich jetzt weiß dass sowas wie ListOf ,QueueOf und soweiter gibt ist bestimmt für späterer Projekte sehr interessant. Vll schreibe ich auch Version mit ListOf um das dann mal zu testen ob das konvertieren merklich langsamer ist. Schöner wäre es schon wenn man es in ListOf hätte.

    Achso ich habe mir den Backgroundworker mal angeschaut und schon eine Frage dazu -> alle Subs die in dem DoWork teil aufgerufen werden (oder subs die in diesen subs aufgerufen werden), werden in dem thread vom BGW gestartet ist das richtig?
    Die ganzen Subs sind in einer Klasse, welche in dem GUI-Thread erstellt wird. Ich muss auch in anderen threads auf die subs der klasse zugreifen und zwar immer auf die selbe, da sie Properties besitzt die ich überall brauche. Gibt es da Probleme?
    Alles was im BGW-DoWork-Teil bearbeitet wird läuft in dem BGW-Thread. Vom BGW-Thread aus hast du Zugriff auf alle Properties und Subs - ganz egal wo sie stehen. Abschmieren tut das ganze lediglich wenn du irgendwo versuchst auf Forms/Controls zuzugreifen.
    Willst du, das sich die Controls ändern (Label-Texte, DisplayControl, etc), dann teile das der übergeordneten Klasse mit: mittels ProgressChanged-Event des BGW. Im BGW-Thread einfach BackgroundWorker1.ReportProgress(...) aufrufen. Einen Prozentwert wirst du wohl nicht liefern können (=> 0, ist egal), wohl aber eine Information die angibt, was getan werden soll - Display soll neue Daten zugewiesen bekommen etc.

    lg
    Das mit den Controls war bewusst...Hier gibt es ja ein gutes Tutorial ->

    HTML-Quellcode

    1. http://www.vb-paradise.de/allgemeines/tipps-tricks-und-tutorials/allgemein/61500-multithreading-mit-backgroundworker/


    Bei den Properties war ich mir nicht sicher. Danke dir aber nun schon ^^

    Das wars dann erstmal! Danke an FreakJNS und natürlich auch ErfinderDesRades

    Werde bestimmt weiterer Fragen haben. :D