BlockingCollection Remove

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

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

    BlockingCollection Remove

    Hallo,

    Es wird eine Methode "Remove" gesucht, mit der aus einer BlockingCollection ein beliebiger Eintrag entfernt werden kann.

    Die Standard-Collection kann in diesem Fall nicht verwendet werden da diese nicht zusammen mit MultiThread verwendet werden kann. Wenn von mehr als einem Thread auf eine Collection zugegriffen werden soll, muss BlockingCollection eingesetzt werden.

    Auf der Webseite stackoverflow.com/questions/56…from-a-blockingcollection wird eine Funktion zum Entfernen eines Eintrags aus einer BlockingCollection vorgestellt.

    Wenn der C# Code in VB.Net umgewandt wird, kommt folgender Code heraus:

    VB.NET-Quellcode

    1. Public Shared Function Remove(Of T)(self As BlockingCollection(Of T), itemToRemove As T) As Boolean
    2. SyncLock self
    3. Dim comparedItem As T
    4. Dim itemsList = New List(Of T)()
    5. Do
    6. Dim result = self.TryTake(comparedItem)
    7. If Not result Then
    8. Return False
    9. End If
    10. If Not comparedItem.Equals(itemToRemove) Then
    11. itemsList.Add(comparedItem)
    12. End If
    13. Loop While Not (comparedItem.Equals(itemToRemove))
    14. Parallel.ForEach(itemsList, Function(t) self.Add(t))
    15. End SyncLock
    16. Return True
    17. End Function


    Bei dem Befehl ...

    VB.NET-Quellcode

    1. Parallel.ForEach(itemsList, Function(t) self.Add(t))

    ... werden mehrere Fehler angezeigt:

    BC32089 "t" ist bereits als Typparameter dieser Methode deklariert.

    BC30518 Fehler bei der Überladungsauflösung, da keine zugreifbare "ForEach" mit diesen Argumenten aufgerufen werden kann: ...

    Beim Beseitigen der Fehler bin ich nicht weiter gekommen.

    Wenn der Befehl in ...

    VB.NET-Quellcode

    1. Parallel.ForEach(Of T)(itemsList, Function(V) self.Add(V))


    ... geändert wird, werden nur noch zwei Stellen bemängelt:

    self.Add(V) :

    BC30491: Der Ausdruck ergibt keinen Wert.

    Dieser Fehler wird gleich zweimal angezeigt.

    Gibt es dennoch eine funktionierende Lösung?
    Für den Anfang kann ich Dir nur den ersten Fehler erklären: Da C# case-sensitive ist, VB.Net jedoch nicht, ist T inakzeptabel, da es im Prozedurkopf als Template/Typ-Platzhalter verwendet wird.

    @BigBen2003
    Laut erster Suchergebnisse gehört in die Zeile aber auch keine Function, sondern eine Sub. Probier mal das:

    VB.NET-Quellcode

    1. Parallel.ForEach(itemsList, Sub(x) self.Add(x))
    Aber Achtung: Es ist nun syntaxfehlerfrei. Ob es das macht, was Du erwartest? Keine Ahnung.
    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.

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

    Abhängig davon was du machst willst du evtl. Sogar eine normale collection mit locks verwenden. Wenn du z.b. nur einen lese und einen schreibthread hast dürfte dies im schnitt performanter sein...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Hallo,

    im Projekt laufen mehrere Threads gleichzeitig, die auf die gleiche Liste zugreifen, daher "BlockingCollection".

    Zum Befehl "Parallel.ForEach" wurde in diversen Testszenarien festgestellt, dass die Reihenfolge der Einträge nicht mehr mit denen in der Ausgangssituation übereinstimmt.

    Alternativ zum Parallel.ForEach-Befehl kann auch eine Standard For each Schleife verwendet werden, wenn die Reihenfolge der Einträge wichtig ist:

    VB.NET-Quellcode

    1. self = New BlockingCollection(Of T)
    2. For Each x As T In itemsList
    3. self.Add(x)
    4. Next


    In der BlockingCollection gibt keine Befehle zum Austauschen bzw. Entfernen von Einträgen. Diese Befehle bewirken das gleiche:

    Ersetzen:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Shared Function Replace(Of T)(self As BlockingCollection(Of T), itemSearch As T, itemToReplace As T) As Boolean
    2. SyncLock self
    3. Dim mynewList As IEnumerable(Of T) = self.Select(Of T)(Function(mySelectItem) If(mySelectItem.Equals(itemSearch), itemToReplace, mySelectItem))
    4. self = New BlockingCollection(Of T)
    5. 'Parallel.ForEach(Of T)(mynewList, Sub(x) self.Add(x)) ' Dieser Befehl wirft die Reihenfolge in der BlockingCollection durcheinander
    6. For Each x As T In mynewList
    7. self.Add(x)
    8. Next
    9. End SyncLock
    10. Return True
    11. End Function



    Entfernen:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Shared Function Remove(Of T)(self As BlockingCollection(Of T), itemToRemove As T) As Boolean
    2. SyncLock self
    3. Dim comparedItem As T
    4. Dim itemsList As List(Of T) = New List(Of T)()
    5. Do
    6. Dim result As Boolean = self.TryTake(comparedItem)
    7. If Not result Then
    8. Return False
    9. End If
    10. If Not comparedItem.Equals(itemToRemove) Then
    11. itemsList.Add(comparedItem)
    12. End If
    13. Loop While Not (comparedItem.Equals(itemToRemove))
    14. 'Parallel.ForEach(Of T)(itemsList, Sub(x) self.Add(x)) ' Dieser Befehl wirft die Reihenfolge in der BlockingCollection durcheinander
    15. self = New BlockingCollection(Of T)
    16. For Each x As T In itemsList
    17. self.Add(x)
    18. Next
    19. End SyncLock
    20. Return True
    21. End Function

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