C#安全线程"刷新"并发字典的内容

时间:2016-05-27 21:04:06

标签: c# multithreading concurrentdictionary

我使用接收列表的方法更新字典。此列表包含应存储在字典中的更新值。例如:我的值1,2,3,4存储在我的字典中。线程尝试使用列表0,1,3,5更新字典中的值。我的刷新"该线程中的方法需要从字典中删除2,4,并添加0,5。

我有多个线程试图这样做"刷新"快速连续,所以我想确保他们的操作不会重叠并弄乱字典。因此,我需要每个尝试更新字典的线程在完成下一个线程之前完成其操作。我还需要确保按照线程尝试更新字典的顺序更新字典。

在我当前的代码中,线程创建一个新列表,然后调用Refresh()来更新SubscriptionCache中的字典。我让每个线程在创建新列表之前在3-8毫秒之间休眠,然后使用新列表刷新字典。

在这里查看我的代码:

public static class SubscriptionCache
    {
        private static ConcurrentDictionary<int, Subscription> _firstPartySubscriptionIds = new ConcurrentDictionary<int, Subscription>();

        //This compares the contents of the dictionary and new list,
        then updates the dictionary accordingly.
        internal static void Refresh(IEnumerable<Subscription> firstPartySubscriptionIds)
        {
          lock(_firstPartySubscriptionIds)
          {
            try
            {
                Compare(firstPartySubscriptionIds, true).ForEach((s) =>
                {
                    var t = _firstPartySubscriptionIds.TryAdd(s.GetHashCode(), s); Print("Added" + s.SystemID + " Success: " + t + " With Key: " + s.GetHashCode());
                });

                Compare(firstPartySubscriptionIds, false).ForEach((s) =>
                {
                    var t = _firstPartySubscriptionIds.TryRemove(s.GetHashCode(), out s); Print("Removed" + s.SystemID + "Success: " + t + " With key: " + s.GetHashCode());
                });


               LastRefreshedOn = DateTime.Now;
            }
            catch { }
          }
        }

        private static List<Subscription> Compare(IEnumerable<Subscription> firstPartySubscriptionIds, bool reverse)
        {
            var masterList = _firstPartySubscriptionIds.Values.ToList();
            var newList = firstPartySubscriptionIds.ToList();
            var returnList = new List<Subscription>();

            if (reverse == false)   // Returns elements in the old list which are NOT in the new list
            {
                foreach (Subscription s in masterList)
                {
                    if (!newList.Contains(s))
                    {
                        returnList.Add(s);
                    }
                }
            }
            else    //Returns elements in the new list which are NOT in the old list
            {
                foreach (Subscription s in newList)
                {
                    if (!masterList.Contains(s))
                    {
                        returnList.Add(s);
                    }
                }
            }
            return returnList;
        }

1 个答案:

答案 0 :(得分:1)

ConcurrentDictionary不仅可以神奇地使涉及多个线程的所有内容都能正常工作。它只是使结构的所有方法在逻辑上都是原子的。如果您希望将单个原子操作执行多个操作(您似乎想要执行此操作),则需要显式管理线程以执行此操作(即锁定)。