Datagridview Scrollbalken verschwindet

  • VB.NET
  • .NET (FX) 4.5–4.8

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

    Datagridview Scrollbalken verschwindet

    Hallo zusammen,

    ich habe ein Datagridview und ein DataTable.
    Das DataTable wird während der Laufzeit mit Daten gefüttert (aus einem Hintergrundprozess!):

    VB.NET-Quellcode

    1. Dim row As String() = {"1", "2", "3", "4", "5"}

    VB.NET-Quellcode

    1. datatablexyz.Rows.Add(row)

    Die DataSource des Datagridview wird folgendermaßen festgelegt:

    VB.NET-Quellcode

    1. dgvxyz.DataSource = datatablexyz

    Wenn sich die Daten im DataTable ändern, ändert sich im DataGridview nichts.
    Wenn ich die Neuzeichnung/Bindung mit DataGridView.Refresh() erzwinge, erscheinen zwar die Einträge, aber der Scrollbalken verschwindet und das Datagridview sieht allgemein "kaputt" aus.

    Gibt es hier eine alternative Herangehensweise?
    Du must eine BindingSource zwischen DataTable (oder besser ein typisiertes DataSet)) und DatagridView packen.
    Das Problem könnte das

    nicerdicer schrieb:

    aus einem Hintergrundprozes
    sein. Da stehen Controls nicht so drauf um könnten zu den genannten Fehlverhalten führen. Was konkret heißt

    nicerdicer schrieb:

    das Datagridview sieht allgemein "kaputt" aus
    Lad mal bitte forenintern n Screenshot hoch.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @FormFollowsFunction Ich habe einmal simpel das Datatable als DataSource der BindingSource gesetzt und dann als DataSource des DataGridView die BindingSource, das Ergebnis ist unverändert. Eventuell mache ich da etwas falsch.

    @VaporiZed Meine Daten kommen aus einem Hintergrundthread, das soll auch so bleiben^^.
    Screenshot hilft hier nichts, im Endeffekt verschwindet wie gesagt die Scrollbar vertikal) und scrollen mit einem Mausrad ist nicht möglich. Ich muss in das Datagridview klicken und mit der Pfeiltaste nach unten navigieren um die neusten Einträge zu sehen...
    Wie könnte ich sonst aus einer rekursiven Funktion die Daten in ein Datatable packen?
    Dass die Daten aus nem Nebenthread kommen, darf auch so bleiben. Sie müssen nur im Hauptthread in die DataTable.
    Das heißt, dass die Daten vom 2. Thread mittels Me.Invoke() in die DataTable geschrieben werden. Beispiel:

    VB.NET-Quellcode

    1. Private Sub PutDataIntoDataTableFromAnotherThread()
    2. Dim Data = GetDataFromAnotherThread()
    3. Me.Invoke(Sub() PutDataIntoDataTable(Data))
    4. End Sub
    5. Private Sub PutDataIntoDataTable(Data As WasAuchImmer)
    6. 'hier die Daten in die DataTable schreiben
    7. End Sub

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Wenn ich schonmal hier bin könnte ich ja noch eine Frage stellen...
    Der Hintergrundprozess führt in einem Do While Loop eine Funktion immer wieder aus, dementsprechend wächst die Speichernutzung auch ununterbrochen.
    Kann ich dem entgegenwirken?

    VB.NET-Quellcode

    1. For i As Integer = 0 To threadcount
    2. Dim thread As Thread = New Thread(Async Sub(t)
    3. Do While justdoit = True
    4. DoSomething().Wait()
    5. Loop
    6. End Sub)
    7. threadlist.Add(thread)
    8. Next
    9. For Each t As Thread In threadlist
    10. t.Start()
    11. Next
    Wenn man davon absieht, dass da ein interessantes/für mich schwer nachvollziehbares Nebenläufigkeitskonstrukt kreiert wurde (Alternative ggf. im Thread Async/Await, Stichwort Parallel bzw. Task.WhenAll/WhenAny): Wenn viele Daten vor der Verarbeitung gesammelt werden müssen, bevor diese verarbeitet wurden, tja, dann ist es so. Dazu müsstest Du schon verraten, was da im Groben ablaufen soll. Noch klingt es nach: Sammle in x Threads viele Daten und (spekulativ, da nicht im Code zu sehen) wenn alle Threads ihre Daten gesammelt haben, dann werte alles aus.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed

    Im Endeffekt wird bei jedem Aufruf 1 neue Zeile in das DataTable geschrieben.
    Beim Async/Await hatte ich das Problem, dass nicht auf die Ausführung des Tasks gewartet wurde, daher das DoSomething.Wait(), vermutlich sollte ich das aber noch einmal genauer prüfen.
    Also grober Ablauf:
    1. Rest Request
    2. Antwort zu row basteln (String Array)
    3. Row in Datatable einfügen.

    Würde es hier helfen anstatt lokaler Variablen globale zu verwenden? In der Theorie wird dann ja nur einmal der Platz für die Variablen reserviert.
    Bitte korrigiere mich hier wenn ich hier falsch liege.
    Eine Zeile pro Thread? Hast Du getestet, ob das schneller und RAM-sparsamer als alle Zeilen in einem Thread ist? Aber bezüglich Speicher: Ist es denn katastrophal viel oder geht bei sehr vielen Daten um 5 oder 20 MB? Letzteres würde mich vollkommen kalt lassen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed

    Ahh das Codekonstrukt ist noch eine schlechte Kopie von einem alten Programm, tatsächlich handelt es sich nur um einen Thread!
    ->

    Quellcode

    1. threadcount
    ist in dem Fall 0.

    Bei der Speichermenge geht es um ca 500kb pro Abfrage die das Programm mehr beansprucht. Bei ~1 Abfrage pro Sekunde häuft sich da leider schnell einiges an.
    Du fragst also permanent nebenläufig Daten an, die dann pro Sekunde 500 KB Daten in Dein Programm schaufeln. Und die gesamten 500-KB-Daten speicherst Du dann in Deiner DataTable, also im RAM. Ist das richtig? Schmeißt Du dann auch irgendwann wieder was aus der DataTable raus? Oder erst alles zu Programmende? Ist das so gewollt, dass sich dann pro Stunde 1,8 GB Daten ansammeln, also im Sinne von: brauchst Du alle Daten, die da reinflattern? Oder brauchst nur einen Teil pro Zeile bzw. nicht alle Zeilen?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Sofern 1 Zeile mit 5 Spalten im Datatable/Datagridview 500kb hat dann ja, das bewzeifle ich aber^^
    Mit einer Websocketverbindung (andere Datenquelle) habe ich das Problem nicht, da ist es schon wild wenn ich mal über 100mb Nutzung komme.

    Die Daten würde ich gern zur Runtime behalten (alle Zeilen). Was nach Beendigung des Programms passiert ist mir im Augenblick noch egal.
    Da kann ich Dir grad inhaltlich nicht folgen. Bei mir kommt an:
    Du bezweifelst, dass eine DataTable-Zeile 500 KB aufnehmen kann. Ich seh da kein Problem.
    Du brauchst zwar jede ankommende Zeile, aber nicht die vollen 500 KB, die da ankommen, sondern nur ein Teil davon. Ist ein Vorabfiltern nicht möglich? Ich bin bei REST, SQL, DB und Co. sowas von raus. :S
    Bei Websocket hast Du irgendein Problem nicht, ich vermute, dass da so viele Daten kommen, aber sicher bin ich mir nicht, was Du da aussagen wolltest.
    Dass die Daten nach Programmende ohne Speichern eh verloren gehen und der Speicher freigegeben wird, darum kümmert sich der Garbage Collector. Das Thema Daten-Dauer-Speichern/Persistieren wollte ich auch gar nicht anreißen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ich meinte, dass das String Array mit 5 Einträgen == eine Ziele im DataTable 500kb benötigt glaube ich nicht.
    Daher habe ich die Erfahrung mit der Websocket Verbindung beschrieben.

    Die 500kb pro Abfrage beziehen sich nicht zwingend auf die Daten die von der Website kommen, sondern auf die Speichermenge, welche die Funktion bei jedem Aufruf erneut in Anspruch nimmt.