ConcurrentDictionary является потокобезопасным для редактирования значения после GetOrAdd?

Я использую метод GetOrAdd параллельного словаря для получения списка значений, а затем со ссылкой на этот список значений, которые я редактирую. Это потокобезопасно, чтобы сделать это таким образом?

Первый метод — я добавляю значение, а второй — очищаю список.

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();
        }
    }
}

person Evan Larsen    schedule 29.04.2014    source источник


Ответы (2)


Словарь не обеспечивает защиты сохраненного значения. Единственное, чем он управляет, — это гарантировать, что сопоставление ключей со значениями остается согласованным. Вам по-прежнему необходимо защищать данные объектов, хранящихся с помощью соответствующей блокировки.

person Dark Falcon    schedule 29.04.2014
comment
Как насчет метода AddOrUpdate в ConcurrentDictionary? Является ли делегат обновления потокобезопасным? - person Evan Larsen; 30.04.2014
comment
Нет. Ни добавление, ни обновление делегатов не вызываются внутри блокировки. - person Dark Falcon; 30.04.2014

ConcurrentDictionary делает безопасным получение и добавление потока объекта value. После того, как вы получили объект value, несколько потоков, обращающихся или изменяющих атрибуты одного и того же object, не являются потокобезопасными.

person T McKeown    schedule 29.04.2014