Multithreading und For each rows ....

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

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von BigBen2003.

    Multithreading und For each rows ....

    Hallo,

    in einer App sind mehrere Threads aktiv, und greifen paralell auf eine DataSet Table zu.

    Wenn eine Reihe von DataRows durchlaufen werden sollen, verwende ich meistens For-Each-Schleifen.

    Das geht solange gut, wie die Auflistung nicht von einem anderen Thread geändert wird.

    Beispiel:

    VB.NET-Quellcode

    1. Dim myTable = from myTab in myDTS.Table where myTab.Column1 = true
    2. For each myRow in myTable
    3. ' ....
    4. next


    Der Code dient lediglich zu Veranschaulichung.
    Damit kei anderer Thread während des Durchlaufens der Auflistung diese ändert, wird bislang auf SyncLock zurückgegriffen. Dadurch werden allerdings alle andere Threads in eine Wartestellung versetzt, sofern diese auch auch die gleiche Tabelle zugrifen wollen.

    Gibt es eine alternative Lösung, die nicht auf SyncLock zurückgreift?

    SyncLock setze ich nur ungern ein, da dieser Befehl ziemlich performancelastig ist.

    Hat jemand eine alternative Lösung?
    DataTable ist nicht Thread-Sicher..d.H. das lesen kann asynchron passieren, das schreiben aber nicht!
    Um das schreiben asynchron zu gestalten empfielt es sich das DataTable in jedem Thread zu clonen..
    ..und nach allen schreibzugriffen diese clone zusammenzuführen!


    stackoverflow.com/questions/79…a-threaded-class-instance

    experts-exchange.com/questions…ble-with-Multithread.html

    stackoverflow.com/questions/98…-in-one-datatable-c-sharp
    @BigBen2003 Überlege genau, was die einzelnen Threads tun.
    Wenn deren Einträge (nicht der Zugriff) in die Tabelle disjunkt sind, überlege, ob Du die Tabellen vereinzelst, wie @Morrison schreibt.
    Greifen sie schreibend auf dieselben Daten zu, musst Du das in einem einzigen Thread in der richtigen Reihenfolge tun.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo,

    Morrison schrieb:

    Um das schreiben asynchron zu gestalten empfielt es sich das DataTable in jedem Thread zu clonen.


    Wenn ich die Thematik richtig gelesen habe, müssen alle Befehle für Schreibzugriffe zunächst in ein Array aufgenommen werden; die anschließend von einem "SchreibThread" tatsächlich ausgeführt werden.

    Lese-Zugriffe können hingegen von den anderen Threads direkt ausgeführt werden?

    Statt mit einer For-Each-Schleife kann man auch mit TakeWhile bzw. Take alle Datensätze einer Tablelle einzeln einlesen? Wenn das funktioniert, braucht man keine SyncLocks.
    Hallo,
    Stichwort: "Beschreiben von Datasets"

    Um ein Beschreiben von mehreren Threads ermöglichen zu können, kann man auch
    folgenden Ansatz verfolgen, wie dieser bereits in diversen SQL Servern
    umgesetzt wird:
    1. Datensatz sperren
    2. Datensatz in Bearbeitung nehmen
    3. Änderungen durch den Anwender oder via .net-Code eintragen
    4. Datensatz speichern
    5. Datensatzsperre aufheben

    Wenn beim Sperren eines Datensatzes bereits bemerkt wird, dass dieser
    bereits gesperrt wurde, muss das Verfahren abgebrochen werden.
    alternativ kann auch gewartet werden, bis die Sperre aufgehoben wurde.

    In SQL wird bei dieser Sperre z.Tl. noch zwischen mehreren Sperr-Typen unterschieden:
    • Lese- und Schreibsperre
      Bei gesetzter Sperre kann der Datensatz von anderen weder ausgelesen noch beschrieben werden.
    • Schreibsperre
      Bei gesetzter Sperre kann der Datzsatz von allen nur ausgelesen werden.
      Beschrieben werden kann diese nur von dem, der die Sperre gesetzt hat.
    In .net sollte die Sperr-Verwaltung idealerweise nur von einer Klasse mit allen Methoden und Eigenschaften verwaltet werden.

    Wenn von allen zugreifenden Threads dieses Verfahren eingehalten wird, sollten keine Deadlocks o.ä. mehr auftreten; wenn man von
    unbeabsichtigten Überschreiben eines Datensatzes absieht.

    Oder habe ich hier etwas übersehen?

    Nachtrag:
    Auf der Microsoft Webseite wird das Verfahren dokumentiert.

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