Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concurrent Dictionary AddOrUpdate method 3rd parameter?

private readonly ConcurrentDictionary<string, System.Drawing.Color> _colorSet;      

public void BuildColorSet(IList<string> colorNames, string prefix, bool forceLastToGray)
{
    var size = forceLastToGray ? colorNames.Count - 1 : colorNames.Count;

    int nbHue = 6;
    int nbCycle = (int)Math.Ceiling((double)size / nbHue);

    var saturationMax = nbCycle <= 2 ? 1.0 : 1.0;
    var saturationMin = 0.3;
    var luminanceMax = nbCycle <= 2 ? 0.85 : 0.85;
    var luminanceMin = 0.3;
    var maxSaturationShift = 0.30;
    var maxLuminanceShift = 0.15;

    var interval = 1.0 / Math.Min(size, nbHue);

    var saturationShift = (saturationMax - saturationMin) / (nbCycle - 1);
    saturationShift = Math.Min(saturationShift, maxSaturationShift);
    var luminanceShift = (luminanceMax - luminanceMin) / (nbCycle - 1);
    luminanceShift = Math.Min(luminanceShift, maxLuminanceShift);

    var hueShift = 0.0;

    var saturation = saturationMax;
    var luminance = luminanceMax;
    for(var i = 0; i<size; i++)
    {
        if(i > 0 && (i % nbHue == 0)) // Next Cycle
        {
            saturation -= saturationShift;
            luminance -= luminanceShift;
            hueShift = hueShift == 0 ? interval/2 : 0;
        }
        var hue = interval*(i%nbHue) + hueShift;

        System.Drawing.Color color = HSL2RGB(hue, saturation, luminance);

    _colorSet.AddOrUpdate(prefix + colorNames[i], color, ???);
    }
    if(forceLastToGray)
    {
        _colorSet.TryAdd(prefix + colorNames[colorNames.Count - 1], System.Drawing.Color.LightGray);
    }

    _cssDirty = true;
}

I want to be able to update the dictionary if the color exists with new value. And also add to dictionary if the color is not there in dictionary.
I am using the AddOrUpdate but not able to get the 3rd parameter(form the lambda expression OR delegate method) of the AddOrUpdate method.
Any idea how my 3rd parameter would look like?

like image 356
Ruruboy Avatar asked May 23 '12 23:05

Ruruboy


People also ask

Is ConcurrentDictionary AddOrUpdate thread-safe?

Also, although all methods of ConcurrentDictionary<TKey,TValue> are thread-safe, not all methods are atomic, specifically GetOrAdd and AddOrUpdate. To prevent unknown code from blocking all threads, the user delegate that's passed to these methods is invoked outside of the dictionary's internal lock.

How do you convert ConcurrentDictionary to Dictionary?

You cannot just assign a ConcurrentDictionary to a Dictionary, since ConcurrentDictionary is not a subtype of Dictionary. That's the whole point of interfaces like IDictionary: You can abstract away the desired interface ("some kind of dictionary") from the concrete implementation (concurrent/non-concurrent hashmap).

What is the difference between Dictionary and concurrent Dictionary?

The biggest reason to use ConcurrentDictionary over the normal Dictionary is thread safety. If your application will get multiple threads using the same dictionary at the same time, you need the thread-safe ConcurrentDictionary , this is particularly true when these threads are writing to or building the dictionary.

How do you initialize ConcurrentDictionary?

You can provide some initial data by passing an IEnumerable<KeyValuePair<TKey, TValue>> as a parameter to the constructor, or you can call TryAdd (or AddOrUpdate , or any of the other methods with Add in the name) in a loop after creating the ConcurrentDictionary .


1 Answers

From the documentation:

updateValueFactory Type: System.Func The function used to generate a new value for an existing key based on the key's existing value

This will leave the value in the collection alone if it already exists:

_colorSet.AddOrUpdate(prefix + colorNames[i], color,
            (key, existingVal) =>
            {
                return existingVal;
            });

This will replace the value in the collection with the same one specified for the insert:

_colorSet.AddOrUpdate(prefix + colorNames[i], color,
            (key, existingVal) =>
            {
                return color;
            });

You can perform conditional logic, comparisons between the old value and new value, or update the original object in the function, for example.

_colorSet.AddOrUpdate(prefix + colorNames[i], color,
            (key, existingVal) =>
            {
                if (existingVal.Name == "Red")
                    return existingVal;
                else
                    return color;
            });
like image 55
ulty4life Avatar answered Oct 22 '22 17:10

ulty4life