user1532208
user1532208

Reputation: 305

How to use ConcurrentDictionary(of Integer, Class).TryUpdate?

What is the correct way to update a ConcurrentDictionary with a new value? I am trying AllWidgets.TryUpdate(id, myWidget, myWidget) and it returns false and does not update correctly in this type of scenario:

Public Class Widget
    Public ID As Integer
    Public Name As String
    Public Sub New(ByVal id As Integer, ByVal name As String)
        ID = id
        Name = name
    End Sub
End Class

Dim AllWidgets As New ConcurrentDictionary(Of Integer, Widget)
AllWidgets.TryAdd(1, New Widget(1000, "Widget A"))
AllWidgets.TryAdd(2, New Widget(1001, "Widget B"))

Dim UpdateWidget As New Widget(1001, "Widget BB")
Dim IsUpdated As Boolean = AllWidgets.TryUpdate(2, UpdateWidget, UpdateWidget)

IsUpdated is False

I guess I really don't understand how the third parameter is supposed to work for complex objects.

Upvotes: 1

Views: 588

Answers (1)

Hans Passant
Hans Passant

Reputation: 941635

You'll never get True this way. The first thing you have to do is make Widgets comparable, override GetHashCode() and Equals(). Like this:

Public Class Widget
    ''...
    Public Overrides Function GetHashCode() As Integer
        Return Me.ID.GetHashCode() Xor Me.Name.GetHashCode()
    End Function

    Public Overrides Function Equals(obj As Object) As Boolean
        Dim w = CType(obj, Widget)
        Return w.ID = Me.ID AndAlso w.Name = Me.Name
    End Function
End Class

Now ConcurrentDictionary can compare widgets. You'll get a True return this way:

    Dim UpdateWidget As New Widget(1001, "Widget BB")
    Dim OldWidget As New Widget(1001, "Widget B")
    Dim IsUpdated As Boolean = AllWidgets.TryUpdate(2, UpdateWidget, OldWidget)
    Debug.Assert(IsUpdated)   '' fine

Upvotes: 1

Related Questions