首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#线程安全地“刷新”并发字典的内容

C#线程安全地“刷新”并发字典的内容
EN

Stack Overflow用户
提问于 2016-05-28 05:04:06
回答 1查看 599关注 0票数 0

我正在使用一个接受列表的方法来更新字典。此列表包含应该存储在字典中的更新值。例如:我将值1,2,3,4存储在我的字典中。一个线程尝试使用列表0,1,3,5更新字典中的值。我在该线程中的“刷新”方法需要从字典中删除2,4,然后添加0,5。

我将有多个线程尝试快速连续地执行此“刷新”,因此我希望确保它们的操作不会重叠并扰乱字典。因此,我需要尝试更新字典的每个线程在移动到下一个线程之前完成其操作。我还需要确保字典按照线程尝试更新它的顺序进行更新。

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

下面是我的代码:

代码语言:javascript
复制
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;
        }
EN

回答 1

Stack Overflow用户

发布于 2016-05-28 05:31:29

ConcurrentDictionary不只是神奇地让涉及到多个线程的所有东西都能工作。它只是使结构的所有方法在逻辑上都是原子的。如果您想要将多个操作作为单个原子操作来执行,那么您将需要显式地管理您的线程来执行该操作(即通过锁定)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37492222

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档