Announcement

Collapse
No announcement yet.

Kopieren von List(of T)

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Kopieren von List(of T)

    Hallo Leute,

    ich habe ein Problem, dass ich mir nicht erklären kann:

    Ich habe eine List(of T) namens
    Code:
    m_InsertMessageContainerFIFO.FinishedBuffer
    die durch einen Thread alle 2,5 Sekunden mit dem Inhalt einer anderen Liste befüllt wird. Während des Befüllens wird der Zugriff auf diese List durch ein ManualResetEvent und dessen .Wait-Routinen gesperrt.

    In einer anderen Klasse möchte ich nun zum Verarbeiten der in dieser Liste eingefüllten Objekte eine temporäre Kopie erstellen um die Objekte in FinishedBuffer stückweise nach Abarbeitung herauszulöschen.
    Die Kopie soll mit folgendem Befehl geschehen:
    Code:
    Dim tempList As List(Of InsertMessageContainer) = _
       New List(Of InsertMessageContainer)(m_InsertMessageContainerFIFO.FinishedBuffer)
    Jedoch erhalte ich beim Ausführen manchmal die Exception mit der Message:
    Code:
    Source array was not long enough. Check srcIndex and length, and the array's lower bounds.
    
    StackTrace:
       at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable)
       at System.Collections.Generic.List`1.CopyTo(T[] array, Int32 arrayIndex)
       at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
       at Database.DataObjects.Message_Object.InsertMessages_archiv_Thread_Sub() in Database.DataObjects\Message_Object.vb:line 319
    Da ich aber keine Grenzen und Indizes beim Instanziieren und Kopieren angebe, kann ich mir das ganze nicht erklären. Der Konstruktor sollte doch beim Übergeben einer existierenden Liste auch die Grenzen korrekt setzen?!

    Habt Ihr eine Idee?
    Bin für jegliche Denkanstöße dankbar!

    Gruß
    Johnny

  • #2
    Hallo,

    Während des Befüllens wird der Zugriff auf diese List durch ein ManualResetEvent und dessen .Wait-Routinen gesperrt.
    Ein lock (Monitor.Enter/Exit) wäre besser.

    Verwendest du .net 4.0 -> dort gibts die BlockingCollection<T> welche genau dafür gedacht ist.

    Andernfalls (wegen der Bezeichnung FIFO) verwende statt der List<T> eine Queue<T> denn diese ist FIFO. Schau dich mal nach Producer/Consumer um für Informationen wie die Synchronsisierung stattfinden soll.


    mfG Gü
    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

    Comment


    • #3
      Hallo gfoidl,

      nein ich verwende VS2005 mit .NET 2.0.

      Die Producer/Consumer-Thematik werde ich mir mal anschauen. Vllt. kann ich auch eine Queue im plementieren - das FIFO hast Du in der Hinsicht richtig erkannt, das stammt noch vom Vorgänger.

      Falls ich eine sinnvolle Lösung gefunden habe, melde ich mich wieder.

      Gruß
      Johnny

      Comment


      • #4
        Gibt auf der Startseite vom Visual Studio momentan einen netten Eintrag zum Producer Consumer Problem Ich such mal grad den Link raus.

        So hier:

        http://blogs.msdn.com/b/csharpfaq/ar...r-problem.aspx

        Ist allerdings .NET 4.0

        Comment


        • #5
          Hallo nochmal,

          ich habe das ganze jetzt nochmal angeschaut. Vllt. helfen die weiteren Codeschnipsel weiter:

          Der Ablauf ist folgender:

          1. Listen deklarieren
          Code:
          Private m_FinishedBuffer As List(Of InsertContainer)
          Private m_CurrentBuffer As New List(Of InsertContainer)
          Private m_BufferSafingEnabled As New ManualResetEvent(True)
          2. m_CurrentBuffer wird fortlaufend mit Objekten des passenden Typs befüllt (Add-Methode).

          3. In definierten Abständen wird der Inhalt von m_FinishedBuffer in m_CurrentBuffer kopiert:
          Code:
          m_BufferSafingEnabled.Reset()
          Try
              If (m_ThreadCounter.Wait(MaxWaitTimeSpan)) Then
                  m_FinishedBuffer = m_CurrentBuffer
                  m_CurrentBuffer = New List(Of InsertMessageContainer)
              End If
          Catch ex As Exception
              Throw ex
          Finally
              m_BufferSafingEnabled.Set()
          End Try
          m_ThreadCounter sichert in dem Fall, dass kein Thread mehr auf m_CurrentBuffer zugreift.

          Ich vermute, dass mir die Zeilen
          Code:
          m_FinishedBuffer = m_CurrentBuffer
          m_CurrentBuffer = New List(Of InsertMessageContainer)
          Probleme machen.
          Ich hänge gerade ein bisschen, wird hier in der ersten Zeile nur der Verweis auf eine Liste zugewiesen, oder wird hier tatsächlich der Wert (also die gesamte Liste) "kopiert" bzw. zugewiesen?
          Wenn Ersteres gilt, dann habe ich ja nach Ausführen der zweiten Zeile in beiden Puffern jeweils eine neue Liste, korrekt?

          4. Nach dem kopieren wird dann das Folgende ausgeführt:
          Code:
          Dim tempList As List(Of InsertContainer) = _
             New List(Of InsertContainer)(m_InsertContainerFIFO.FinishedBuffer)
          Diese Liste wird dann wie schon oben beschrieben zum Verarbeiten der darin enthaltenen Elemente genutzt (Löschvorgänge).

          Danke für die Hilfe!

          Gruß
          Johnny

          Comment


          • #6
            Hallo,

            siehe SyncQueue <T> - Eine praktische Job-Queue

            Konvertierungshilfe: C# -> VB.net

            Edit: Deine letzte Antwort hab ich jetzt nicht gelesen


            mfG Gü
            "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

            Comment


            • #7
              Originally posted by gfoidl View Post
              Edit: Deine letzte Antwort hab ich jetzt nicht gelesen
              Meinst Du, ich sollte vom Schlauch runtergehen und gut nachdenken? Ich komm nämlich nicht runter...
              Oder hast Du das wörtlich gemeint, dass Du sie wirklich nicht gelesen hast?

              Gruß
              Johnny

              Comment


              • #8
                Hallo,

                es war wörtlich gemeinst und zwar deshalb:

                Du hast geschrieben
                Die Producer/Consumer-Thematik werde ich mir mal anschauen. Vllt. kann ich auch eine Queue im plementieren
                darauf hab ich einen Link zu einer funktionierenden fetigen Sync-Queue gepostet (allerdings in C# -> daher auch der Link für die Konvertierungshilfe) und deine Antwort kam zeitgleich. In der habe ich nur ein paar Worte gescannt wie "Probleme" und dann erschien es mir nicht sinnvoll weiterzulesen denn eine Eigenimplementation einer Sync-Queue von Scratch wird nie so gut sein als die im Link die von mehrere Leuten bereits kritisch reflektiert wurde. Diesen Punkt unterstelle ich dir einfach mal das du das nicht auf Anhieb schaffen wirst

                Es ist also nicht böse gemeint sondern vergiss deine Implementierung und nimm die fertige.
                Wenn ich gemeint du solltest vom Schlauch runter hätte ich das auch - mehr oder weniger - direkt geschrieben


                mfG Gü
                "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

                Comment


                • #9
                  Hallo gfoidl,

                  ok, danke für den Link. Ich hatte auch überlegt, mit dem Coden anzufangen, hatte dann aber deine Antwort gesehen und die Version gleich an meine Bedürfnisse angepasst und manuell getestet. Ich denke, das könnte ganz gut funktionieren.

                  Allerdings habe ich diese Version in der eigentlichen Laufzeit noch nicht getestet, da sind die Datenmengen ungemein höher (ca. 6.500 Objekte pro Sekunde), von daher kann ich noch nicht definitiv sagen, ob es mir wirklich geholfen hat.

                  Du hast Recht, ich hätte auf jeden Fall länger gesessen, wenn ich das so Thread-sicher gestalten wollte, wie es dort (im Link) beschrieben ist.
                  Das C# macht mir jetzt nicht die Probleme, allerdings geht es mit Übersetzer schneller...

                  Danke!

                  Gruß
                  Johnny

                  Comment

                  Working...
                  X