Reputation: 2036
¿It's safe and correct, inside parallel.foreach, add and read to/from a concurrent bag?
Example (in VB.net):
Dim myConcurrentBag As New ConcurrentBag(Of myClass)
Parallel.ForEach(elementList, Sub(element)
Try
Dim newObject as New myClass
newObject.Property1 = element.PropertyX
' Check if item is inserted inside myConcurrentBag
' ¿IS THIS LINE CORRECT?
If (myConcurrentBag.Select(Function(x) x.Property1).Contains(newObject.Property1)) Then
Return
End If
myConcurrentBag.Add(newObject)
Catch ex As Exception
' Log exception
End Try
End Sub)
And finally, this is the best way to do it, right?:
Dim myConcurrentDictionary As New ConcurrentDictionary(Of String, myClass)
Parallel.ForEach(elementList, Sub(element)
Try
Dim newObject as New myClass
newObject.Property1 = element.PropertyX
' Check if item is inserted inside myConcurrentDictionary
' ¿IS THIS LINE CORRECT?
If (myConcurrentDictionary.ContainsKey(newObject.Property1)) Then
Return
End If
myConcurrentDictionary.TryAdd(newObject.Property1, newObject)
Catch ex As Exception
' Log exception
End Try
End Sub)
Upvotes: 0
Views: 256
Reputation: 184
I understand your intention is to have unique items in terms of PropertyX after the execution of Parallel.ForEach is completed.
As enumeration of ConcurrentBag runs over a point in time snapshot of the content, another task may insert an object with the same value of the property without Select() seeing this new object, and thus the uniqueness requirement will not be met.
Please check this question as well -- Adding and removing elements of a ConcurrentBag during enumeration
Upvotes: 1