Eine seltsame Exception

  • VB.NET
  • .NET (FX) 4.0

Es gibt 45 Antworten in diesem Thema. Der letzte Beitrag () ist von sonne75.

    Ich verstehe jetzt, was du meinst. Allerdings mache ich ja jedes Mal nach dem Schreiben .BindingsReset() (gut, davor sind sie noch gebunden). Ich habe erst mal das mit .AddXXRow aus dem Nebenthread herausgenommen (so häufig passiert es ja nicht), ich denke, das sollte erstmal die größten Kollisionen beseitigen.

    Die Frage ist ja, warum du es sagst:

    ErfinderDesRades schrieb:

    Der NebenThread darf nicht ins Dataset schreiben, solange wie auch immer ein Databinding besteht.


    Denn bisher lag die Exception definitiv nicht an DataBinding, sondern wurde im Setter der neuen Row ausgelöst. Solange ich kein .ResetBindings() gemacht habe, ist das Programm auch nicht abgestürzt, sondern hat einfach das Falsche angezeigt (bzw. nicht aktualisiert).

    Die Daten sollen schon zeitnah (deutlich weniger als eine Sekunde Verzögerung) in der GUI angezeigt werden (also in DS geschrieben werden), mir bringt also das Sammeln nicht wirklich was... Ich müsste, wenn, dann jeden neuen Datensatz in den GUI-Thread übergeben. Es sind halt im Schnitt 10-15 Sachen, plus Berechnungen - ich denke, .ResetBindings() ist schneller, oder?
    Warum ich das sage: Weil eine Zuweisung an ein gebundenes Objekt mit Sicherheit einen Schreibzugriff auf das angebundene Control nach sich zieht - das ist Databinding.
    Und Schreibzugriffe auf Controls aus einem NebenThread heraus sind nicht zulässig - das ist nicht stabil.

    sonne75 schrieb:

    einfach das Falsche angezeigt (bzw. nicht aktualisiert)
    Du beschreibst ja selbst ein höchst verdächtiges Fehlverhalten - sieht doch sehr nach Instabilität aus, odr?

    ResetBindings ist übrigens auch teuer - da wird das ganze DGV neu befüllt.

    ErfinderDesRades schrieb:

    Weil eine Zuweisung an ein gebundenes Objekt mit Sicherheit einen Schreibzugriff auf das angebundene Control nach sich zieht - das ist Databinding.
    Und Schreibzugriffe auf Controls aus einem NebenThread heraus sind nicht zulässig - das ist nicht stabil.

    Wie schon gesagt, die Controls wurden einfach nicht aktualisiert, da standen noch die Daten von vorhin drin, es gab aber keine Exception.

    ErfinderDesRades schrieb:

    ResetBindings ist übrigens auch teuer - da wird das ganze DGV neu befüllt.


    Das ist natürlich ein Argument...
    Die Frage ist, was ist schneller: das zweite Befüllen von Daten (müsste ja dann eine Datenklasse erst beschreiben, die ich an GUI-Thread übergeben, damit DS beschrieben wird) oder ResetBindings()...
    Ich könnte es ja ausmessen, wie lange die Vorgänge dauern.
    Reicht es, die Zeit vor und nach .ResetBindings() auszulesen? Oder werden sie nur angestoßen?

    @ErfinderDesRades
    Mein neuester Spleen ist übrigens, dass der NebenThread sein eigenes Dataset hält, von dem ein Klon (Dataset.GetChanges) dann gelegentlich ins Gui-Dataset eingemergt wird.
    Fürs Mergen gibts Extra-Befehle im Dataset.

    Habe es erst jetzt gesehen. Mein Problem ist das "gelegentlich", denn ich muss die Änderungen IMMER sofort einpflegen, damit sie im GUI-Thread angezeigt werden. Gibt es da irgendein Vorteil von dieser Methode dann noch, ggü. der Datenklasse (außer einmaliger Schreibaufwand für mich)?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „sonne75“ ()

    Ich habe jetzt versucht zu messen mit

    VB.NET-Quellcode

    1. Dim time2 = Now.ToString & Now.Millisecond

    jeweils am Anfang und Ende, dann setze ich Breakpoint danach und schaue mir die Zeiten an. Leider sind sie komplett identisch, egal, ob 70 Zeilen Zuweisungen oder .ResetBindings(). Habe ich irgendwie einen Denkfehler oder ist es einfach so schnell?

    @ErfinderDesRades
    Kannst du mir ein Beispiel geben, wie du das Klonen machst? Du musst ja jedes Mal neuen Klon erstellen, der die vorigen Änderungen enthält, oder?
    Bei MSDN steht
    Ruft eine Kopie des DataSet ab, die sämtliche seit dem letzten Laden oder seit dem letzten Aufruf von AcceptChanges vorgenommenen Änderungen enthält.

    Was für eine Kopie wird denn nach dem Mergen wieder übergeben? Doch nicht die Ganze, oder?
    muss man testen, kann mir aber vorstellen, das ist sehr zackig.

    Beim mergen werden die Rows anhand ihrer Primkeys verglichen:
    Findet sich eine Übereinstimmung, so werden die Spaltenwerte der Merge-Quell-Row in die ZielRow übertragen - die ZielRow löst dann eine Binding-Aktualisierung aus.
    Findet sich keine Übereinstimmung, so wird eine Komplett-Kopie der QuellRow in der Ziel-Tabelle geadded - auch hier erfolgt eine Binding-Aktualisierung.

    Alle anneren Rows bleiben unangetastet, und lösen auch keine Binding-Aktualisierung aus.

    Und wenn der NebenThread mit Dataset.Getchanges arbeitet, dann erhält er meist nur ein winzkleines Datasetchen - halt nur die Changes.

    Aber warnung: Ich hab mit Merging noch nie rumgespielt, also ich garantiere nicht, dass nur die gemergten Rows Binding-Aktualisierung ausführen.
    Vlt. ists auch so blöd gelöst, dass am Ende eines Mergings auch wieder stumpf alle Rows Aktualisierung auslösen - dann müsste man sich ein Merging selber schreiben (sowas hab ich grad gemacht).

    sonne75 schrieb:

    Was für eine Kopie wird denn nach dem Mergen wieder übergeben?
    der Satz ergibt mir keinen Sinn.
    "Nach dem Mergen" wird nix übergeben. Bei Dataset.Getchanges wird was übergeben, genau gesagt, du bekommst es.
    Also der Vorgang ist

    VB.NET-Quellcode

    1. dim tomerge= NebenThread.Dataset.GetChanges
    2. Gui.Invoke(Sub(tomerge)HauptThread.Dataset.Merge(tomerge))
    (PseudoCode)


    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Ich glaub, es ist mir gerade zu kompliziert... Ich lass mal so drin, wie es ist (neue Rows werden jetzt im GUI-Thread hinzugefügt und die alten da gelöscht). Beim Löschen der Rows wird sichergestellt, dass keine Daten empfangen werden (damit nicht ins Leere geschrieben wird), danach werden nur die Rows beschrieben, die da sind, bzw. dann wieder zuerst neue erstellt.