समसामयिक AddOrUpdate में अद्यतन भाग के लिए क्या जोड़ना है


109

मैं समवर्ती छाया का उपयोग करने के लिए शब्दकोश का उपयोग करते हुए कुछ कोड को फिर से लिखने की कोशिश कर रहा हूं। मैंने कुछ उदाहरणों की समीक्षा की है, लेकिन मुझे अभी भी AddOrUpdate फ़ंक्शन को लागू करने में समस्या हो रही है। यह मूल कोड है:

    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जो अद्यतन के मामले में शब्दकोश में संग्रहीत किए जाने वाले मान को लौटाता है। मैं आपके मामले में अनुमान लगाता हूं (चूंकि आप ऐड और अपडेट के बीच अंतर नहीं करते हैं) यह होगा:

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

यानी Funcहमेशा सेशन का रिटर्न देता है, ताकि ऐड और अपडेट दोनों एक ही मूल्य निर्धारित करें।

BTW: MSDN पृष्ठ पर एक नमूना है ।


4
मैं एक ही मूल्य को जोड़ने या अद्यतन करने के लिए एक फ़ंक्शन खोजने के लिए गंभीरता से जूझ रहा था। thaks
Zapnologica

2
अच्छा उत्तर। केवल Visual Studio में प्रदर्शित AddOrUpdate () के हस्ताक्षर से आप केवल 2 मापदंडों के अर्थ का अनुमान लगा सकते हैं। हालांकि विशिष्ट मामले में, उस @ user438331 के बारे में पूछता है, मुझे लगता है कि एक साधारण इंडेक्सर का उपयोग करके मेरे उत्तर में समाधान बेहतर है।
निकलैस पीटर

7
जैसा कि @NiklasPeter इंगित करता है ( stackoverflow.com/a/32796165/8479 ), आप सामान्य इंडेक्सर का उपयोग करके मूल्य को अधिलेखित करने से बेहतर हैं, क्योंकि आपके मामले में आप मौजूदा मूल्य में रुचि नहीं रखते हैं। बहुत अधिक पठनीय।
रोरी

3
मैं @NiklasPeter के उत्तर पर उपयोगकर्ताओं को इंगित करने के लिए आपके उत्तर को बदलने की सलाह दूंगा। यह एक बेहतर उपाय है।
विल काल्डरवुड

63

मुझे आशा है, कि मैंने आपके प्रश्न में कुछ भी याद नहीं किया, लेकिन ऐसा क्यों नहीं? यह आसान, परमाणु और धागा-सुरक्षित (नीचे देखें) है।

userDic[authUser.UserId] = sessionId;

यदि कोई कुंजी पहले से मौजूद है, तो उस कुंजी के लिए किसी भी मान को अधिलेखित करते हुए, कुंजी / वैल्यू जोड़ी को बिना शर्त के डिक्शनरी में स्टोर करें: इंडेक्सर सेटर का उपयोग करें

(देखें: http://blogs.msdn.com/b/pfxteam/archive/2010/01/08/9945809.aspx )

सूचकांक भी परमाणु है। यदि आप इसके बजाय कोई फ़ंक्शन पास करते हैं, तो यह नहीं हो सकता है:

ये सभी ऑपरेशन परमाणु हैं और समवर्ती पर अन्य सभी कार्यों के संबंध में थ्रेड-सुरक्षित हैं। प्रत्येक ऑपरेशन की परमाणुता के लिए एक ही चेतावनी है जो एक प्रतिनिधि को स्वीकार करते हैं, अर्थात् AddOrUpdate और GetOrAdd। [...] इन प्रतिनिधियों को ताले के बाहर लगाया जाता है

देखें: 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
);


1
हम्म, हाँ, तुम सही हो, GetOrAdd () इस मामले में सरल और पर्याप्त है - इस संकेत के लिए!
निकोलस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.