0

I need help with Parallel.Foreach loop in C#. I have a feeling that sometimes "result" tuple is rewritten by other parallel thread so there is no correct output. It doesn't occur often, but sometimes it spits out bad result.

Scenario: Network device is accessible, everything works fine output is stored in the "result" tuple. But then I when I work with the "result" further, the tuple is sometimes empty even though the output was stored there. Could it be that other thread in parallel processing is erasing the "result" ? Can I make it more threadsafe ?

Tuple <string, int> result;

/*loop through all hosts and execute commands -> In paralel*/
        Parallel.ForEach(devices, (hostname, state) =>
        {
            //because we have multithreading every thread must differentiate -> based on hostname (first value in list) - key is also hostname
            device_checked_with_all_parameters.Add(cleaned_hostname, new List<string> { DateTime.Now.ToString("d.M.yyyy HH:mm:ss"), cleaned_hostname, "", "", "", "" });

                //if stop is pushed break all threads
            if (token.IsCancellationRequested)
            {
                canceled_loop = 1;
                state.Break();
            }

            //PERFORM ACTION ON DEVICE - STORE OUTPUT IN RESULT
            result = core.connect_to_device_and_perform_actions(device_checked_with_all_parameters[cleaned_hostname][1], config_vlan_ids_based_on_type);

         });
marhyno
  • 677
  • 1
  • 8
  • 20
  • 2
    If there are (for example) ten threads, why are they all writing to the same `Tuple`? – mjwills Sep 05 '17 at 13:04
  • Is code posted the only place where object is modified? Code should be locked wherever parallel threads are modifying code. It is best to have one module make all the changes so a single lock can be used to prevent cross-threading. – jdweng Sep 05 '17 at 13:11
  • You always rewriting result when you have more then 1 device. If you have many devices wouldn't it be better to have result per device? – Renatas M. Sep 05 '17 at 13:14
  • @mjwills I was not sure if this is this will be the problem. Okay so I think I will replace the tuple with list or dictionary so it will differentiate for every thread. – marhyno Sep 05 '17 at 13:28
  • `List` and `Dictionary` are also not thread-safe. You likely want `ConcurrentDictionary` - or use `AsParallel().Select().ToList()` like from https://stackoverflow.com/questions/13942998/running-a-simple-linq-query-in-parallel . – mjwills Sep 05 '17 at 13:47

0 Answers0