-1

I've read a few links here but i couldn't come up with an answers to my question.

What i'm trying to achieve is to add the results of the Parallel.ForEach into a ConcurrentDictionary. However, how can i be sure that i'm adding the result of the iteration instead of a null value ?

I mean: I want to add the variable after the operation is done. I'm worried that i may add a null value (i.e: add to the collection an uncomplete iteration).

My code goes below. Thanks for any tip.

I've also read about using lock being faster than the ConcurrentDictionary but i think that on my case it won't make an significant difference.

Thanks in advance.

public Dictionary<string,IMagickImage> ComposedImages { get; private set; }
        public ParallelImageComposer(Dictionary<string,MagickImage> InputImages, MagickImage InkZoneImage, int OrientationNumber)
        {

            var resultCollection = new ConcurrentDictionary<string, IMagickImage>();            
            Parallel.ForEach(InputImages, CurrentKeyValuePair =>
            {
                var img = new ImageComposer(InkZoneImage, CurrentKeyValuePair.Value, OrientationNumber).ComposedImage;
                resultCollection.TryAdd(CurrentKeyValuePair.Key, img);
            });            
            ComposedImages = resultCollection.ToDictionary(x => x.Key, x => x.Value);  
paboobhzx
  • 109
  • 10

1 Answers1

0

Accordingly to 70-483 exam reference:


Using concurrent collections

When working in a multithreaded environment, you need to make sure that you are not manipulating shared data at the same time without synchronizing access. The .NET Framework offers some collection classes that are created specifically for use in concurrent environments, which is what you have when you’re using multithreading. These collections are thread-safe, which means that they internally use synchronization to make sure that they can be accessed by multiple threads at the same time.

Those collections are the following: - BlockingCollection

  • ConcurrentBag

  • ConcurrentDictionary

  • ConcurrentQueue

  • ConcurrentStack

  • ConcurrentDictionary

A ConcurrentDictionary stores key and value pairs in a thread-safe manner. You can use methods to add and remove items, and to update items in place if they exist.

Shows the methods that you can use on a ConcurrentDictionary

var dict = new ConcurrentDictionary<string, int>();

if (dict.TryAdd("k1", 42))
{
    Console.WriteLine("Added");
}

if (dict.TryUpdate("k1", 21, 42))
{
    Console.WriteLine("42 updated to 21");
}

dict["k1"] = 42; // Overwrite unconditionally
int r1 = dict.AddOrUpdate("k1", 3, (s, i) => i * 2);
int r2 = dict.GetOrAdd("k2", 3);

When working with a ConcurrentDictionary you have methods that can atomically add, get, and update items. An atomic operation means that it will be started and finished as a single step without other threads interfering. TryUpdate checks to see whether the current value is equal to the existing value before updating it. AddOrUpdate makes sure an item is added if it’s not there, and updated to a new value if it is. GetOrAdd gets the current value of an item if it’s available; if not, it adds the new value by using a factory method.


So, to be sure you are adding the result of the iteration I would write something like this, and maybe test the return of my method.

public ConcurrentDictionary <string,IMagickImage> ParallelImageComposer(Dictionary<string,MagickImage> InputImages, MagickImage InkZoneImage, int OrientationNumber)
{
    var resultCollection = new ConcurrentDictionary <string,IMagickImage>();

    Parallel.ForEach(InputImages, CurrentKeyValuePair =>
    {
        var img = new ImageComposer(InkZoneImage, CurrentKeyValuePair.Value, OrientationNumber).ComposedImage;

        resultCollection.TryAdd(CurrentKeyValuePair.Key, img);
    });

    return resultCollection;
}
Andrew Paes
  • 1,940
  • 1
  • 15
  • 20
  • I understood it, thanks. Perhaps, using a ParallelLoopResult and checking if everything completed sucessfully before returning ? The documentation was really useful also to clarify a few points. Thanks ! – paboobhzx Oct 15 '18 at 18:11