সাম্প্রতিক অভিধান অভিধান অ্যাডআরআপটেটে আপডেট অংশের জন্য কী যুক্ত করা যায়


109

সমকালীন অভিধান ব্যবহার করতে অভিধান ব্যবহার করে কিছু কোড পুনরায় লেখার চেষ্টা করছি। আমি কয়েকটি উদাহরণ পর্যালোচনা করেছি তবে অ্যাডআরআপডেট ফাংশনটি বাস্তবায়নে আমার এখনও সমস্যা হচ্ছে। এটিই মূল কোড:

    dynamic a = HttpContext;
    Dictionary<int, string> userDic = this.HttpContext.Application["UserSessionList"] as Dictionary<int, String>;

   if (userDic != null)
   {
      if (useDic.ContainsKey(authUser.UserId))
      {
        userDic.Remove(authUser.UserId);
      }
   }
  else
  {
     userDic = new Dictionary<int,string>();
  }
  userDic.Add(authUser.UserId, a.Session.SessionID.ToString());
  this.HttpContext.Application["UserDic"] = userDic;

আপডেট অংশের জন্য কী যুক্ত করতে হবে তা আমি জানি না:

userDic.AddOrUpdate(authUser.UserId,
                    a.Session.SessionID.ToString(),
                    /*** what to add here? ***/);

যে কোনও পয়েন্টার প্রশংসা করা হবে।

উত্তর:


220

আপনাকে এমন একটি পাস করতে হবে Funcযা কোনও আপডেটের ক্ষেত্রে অভিধানে সঞ্চিত মানটি দেয় returns আমি আপনার ক্ষেত্রে অনুমান করি (যেহেতু আপনি অ্যাড এবং আপডেটের মধ্যে পার্থক্য করেন না) এটি হ'ল:

var sessionId = a.Session.SessionID.ToString();
userDic.AddOrUpdate(
  authUser.UserId,
  sessionId,
  (key, oldValue) => sessionId);

অর্থাৎ Funcসর্বদা সেশনআইড প্রদান করে, যাতে যুক্ত এবং আপডেট উভয়ই একই মান সেট করে।

বিটিডাব্লু: এমএসডিএন পৃষ্ঠায় একটি নমুনা রয়েছে ।


4
আমি একই মানটিতে যুক্ত করতে বা আপডেট করার জন্য কোনও ফাংশন সন্ধান করতে মারাত্মকভাবে লড়াই করছি। থ্যাक्स
জাপানোলজিকা

2
ভাল উত্তর. ভিজ্যুয়াল স্টুডিওতে প্রদর্শিত অ্যাডআরআপডেট () এর স্বাক্ষর থেকে আপনি কেবলমাত্র 2 টি প্যারামিটারের অর্থ অনুমান করতে পারেন। তবে নির্দিষ্ট ক্ষেত্রে, যে @ ব্যবহারকারী 438331 সম্পর্কে জিজ্ঞাসা করেছে, আমি মনে করি একটি সাধারণ সূচক ব্যবহার করে আমার উত্তরের সমাধানটি আরও ভাল।
নিক্লাস পিটার

7
@NiklasPeter পয়েন্ট আউট (আস stackoverflow.com/a/32796165/8479 ), আপনি ভাল বন্ধ শুধু স্বাভাবিক indexer ব্যবহার করে, মান ওপর দিয়েই লিখতে আপনার ক্ষেত্রে যেহেতু আপনি যদি কোনো বিদ্যমান মান আগ্রহী নন, তাহলে করছি। আরও অনেক পাঠযোগ্য able
ররি

3
আমি আপনার উত্তর @ নিক্লাসপিটারের উত্তরটিতে পয়েন্ট ব্যবহারকারীদের পরিবর্তনের পরামর্শ দিচ্ছি। এটি অনেক উন্নত সমাধান।
উইল ক্যালডারউড

63

আমি আশা করি, আপনার প্রশ্নে আমি কিছু মিস করিনি, তবে কেন ঠিক এইভাবে নয়? এটি সহজ, পারমাণবিক এবং থ্রেড-নিরাপদ (নীচে দেখুন)।

userDic[authUser.UserId] = sessionId;

অভিধানে শর্তাবলীতে একটি কী / মান জুড়ি সংরক্ষণ করুন, কীটি ইতিমধ্যে উপস্থিত থাকলে কীটির কোনও মান ওভাররাইট করে: সূচকের সেটারটি ব্যবহার করুন

(দেখুন: http://blogs.msdn.com/b/pfxteam/archive/2010/01/08/9945809.aspx )

সূচকটিও পারমাণবিক। পরিবর্তে আপনি যদি কোনও ফাংশনটি পাস করেন তবে এটি নাও হতে পারে:

এই সমস্ত অপারেশনগুলি পারমাণবিক এবং সমকালীন অভিধানে অন্য সমস্ত ক্রিয়াকলাপের সাথে থ্রেড-নিরাপদ। প্রতিটি অপারেশনের পারমাণবিকতার একমাত্র সতর্কতা হ'ল অ্যাডআরআউডপেট এবং গেটআরএড নামে একটি প্রতিনিধি গ্রহণ করেন। [...] এই প্রতিনিধিদের তালার বাইরে ডাকা হয়

দেখুন: http://blogs.msdn.com/b/pfxteam/archive/2010/01/08/9945809.aspx


2
হ্যাঁ পারমাণবিক যে এটি একবারে একসাথে ঘটে এবং অর্ধেক ঘটতে বা বাধা পেতে পারে না। তবে এটি নিরাপদ নয় যে আপনার অন্যের আগে অন্য কেউ এটিকে অন্য কোনও কিছুতে পরিবর্তন করতে পারে, সেই ক্ষেত্রে পরিবর্তনটি হারিয়ে যায় এবং আপনি জানেন না যে এটি ঘটেছে, আপনি যদি কেবলমাত্র এটির পরিবর্তন করতে চান যদি মানটি আপনি প্রত্যাশা করেন তবে এটি আপনার জন্য এটি করবে না।
ট্রাম্পস্টার

26

আমি একটি এক্সটেনশন পদ্ধতি প্রয়োগ করে শেষ করেছি:

static class ExtensionMethods
{
    // Either Add or overwrite
    public static void AddOrUpdate<K, V>(this ConcurrentDictionary<K, V> dictionary, K key, V value)
    {
        dictionary.AddOrUpdate(key, value, (oldkey, oldvalue) => value);
    }
}

1

যারা আগ্রহী তাদের জন্য, আমি বর্তমানে একটি কেস বাস্তবায়ন করছি যা "ওল্ডভ্যালু" ওরফে বিদ্যমান মান নতুন ব্যবহারের পরিবর্তে ব্যবহার করার জন্য একটি দুর্দান্ত উদাহরণ (ব্যক্তিগতভাবে আমি "ওল্ডভ্যালু" শব্দটি পছন্দ করি না কারণ এটি এটি নয় পুরাতন যখন এটি একটি সমান্তরাল থ্রেডের মধ্যে থেকে কয়েক প্রসেসর টিক্স আগে তৈরি হয়েছিল))

dictionaryCacheQueues.AddOrUpdate(
    uid,
    new ConcurrentQueue<T>(),
    (existingUid, existingValue) => existingValue
);

6
যদি আপনি বিদ্যমান মানটি পরিবর্তন করতে না চান তবে GetOrAdd()পরিবর্তে আপনার ব্যবহার করা উচিত msdn.microsoft.com/en-us/library/ee378674(v=vs.110).aspx
রোরি

1
এইচএম হ্যাঁ, আপনি ঠিক বলেছেন, GetOrAdd () সহজ এবং এই ক্ষেত্রে যথেষ্ট - এই ইঙ্গিতটির জন্য THX!
নিকোলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.