6

I am using the GetOrAdd method of the concurrent dictionary to retrieve a list of values then with a reference to that list of values I'm editing them. Is it thread-safe to do it this way?

The first method I'm adding a value and the second method I'm clearing the list.

using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;
using Test.Web.Services;

namespace Test.Web.Messaging
{
    public class Dispatch
    {
        private static readonly ConcurrentDictionary<string, IList<Message>> Messages = new ConcurrentDictionary<string, IList<Message>>();

        public static void AddMessage(string id, Message value)
        {
            var msgs = Messages.GetOrAdd(id, new List<Message>());
            msgs.Add(value);
        }

        public static void Send(string id)
        {
             var msgs = Messages.GetOrAdd(id, new List<Message>());
             foreach (var msg in msgs)
             {
                 Connection.Send(id, msg);
             }
             msgs.Clear();
        }
    }
}
Evan Larsen
  • 9,935
  • 4
  • 46
  • 60

2 Answers2

16

The dictionary provides no protection for the value stored. The only thing it manages is ensuring that the mapping of keys to values remains consistent. You still need to protect the data of the objects stored with appropriate locking.

Dark Falcon
  • 43,592
  • 5
  • 83
  • 98
8

The ConcurrentDictionary makes the Getting and Adding of the value object thread safe, nothing more than that. Once you've gotten the value object multiple threads accessing or change attributes of the same object are potentially not thread safe. You would have to implement more concurrency control of property and operations that are vulnerable to thread safety.

T McKeown
  • 12,971
  • 1
  • 25
  • 32
  • *"The `ConcurrentDictionary` makes the Getting and Adding of the `value` object thread safe"* -- You should explain in more details what *"thread safe"* means in this context. It means that the internal state of the `ConcurrentDictionary` is not corrupted. It doesn't mean that the `valueFactory` of the [`GetOrAdd`](https://learn.microsoft.com/en-us/dotnet/api/system.collections.concurrent.concurrentdictionary-2.getoradd) is synchronized. It's not synchronized. Multiple threads might invoke this action in parallel. – Theodor Zoulias Jan 03 '23 at 17:21
  • i answered the immediate question. I never offered that as my answer, if the object that is being stored is getting corrupted it is beyond the control of the ConcurrentDictionary. If there's another question after that, let the OP ask it. – T McKeown Jan 03 '23 at 17:37