2011-11-22 16 views
58

मैं सही इस सोच में हूँ मैं कोई ताले आदि है और सिर्फ शब्दकोश में मूल्य भले ही एक से अधिक थ्रेड करने की कोशिश कर रहा हो सकता है अद्यतन करने हूँ एक समवर्ती शब्दकोशसमवर्ती शब्दकोश सही उपयोग

private ConcurrentDictionary<int,long> myDic = new ConcurrentDictionary<int,long>(); 

//Main thread at program startup 

for(int i = 0; i < 4; i++) 
{ 
    myDic.Add(i, 0); 
} 

//Seperate threads use this to update a value 

myDic[InputID] = newLongValue; 

के सही उपयोग है ऐसा ही करने।

+2

यह निर्भर करता है - है 'newLongValue' की' myDic [InputID] 'पिछले मान पर निर्भर करते हैं? "MyDic" चर नाम के लिए –

+74

1UP! –

+2

आपको दौड़ की स्थिति के लिए सीधे 'myDic [इनपुटपुट]' कुंजी से पहुंचने से बचना चाहिए। आपको 'GetOrAdd' –

उत्तर

52

यह थ्रेड-सुरक्षित द्वारा आपके मतलब पर निर्भर करता है।

MSDN से - How to: Add and Remove Items from a ConcurrentDictionary:

ConcurrentDictionary<TKey, TValue> बहु परिदृश्यों के लिए बनाया गया है। संग्रह से आइटम जोड़ने या हटाने के लिए आपको अपने कोड में ताले का उपयोग करने की आवश्यकता नहीं है। हालांकि, एक थ्रेड के लिए एक मान को पुनर्प्राप्त करना हमेशा संभव होता है, और एक और धागा उसी कुंजी को एक नया मान देकर संग्रह को तुरंत अपडेट करने के लिए होता है।

इसलिए, यह एक असंगत शब्दकोश में एक आइटम के मूल्य का दृश्य दिखाने के लिए संभव है।

+1

एक दिलचस्प बात है! क्या आप अभी भी उस परिदृश्य में लॉक का उपयोग करेंगे? – Jon

+0

@ जोन - यह आपके आवेदन पर निर्भर करता है और क्या यह ठीक है आप। लेकिन मैं कहूंगा कि यदि आप वस्तुओं के लगातार विचार चाहते हैं, तो आपको लॉक में किसी आइटम के प्रत्येक पढ़ने और अपडेट को लपेटना होगा। – Oded

+4

मुझे लगता है कि यह डॉक्टर नहीं कहता है। असंगतता को दृश्य में क्या करना है, यदि दृश्य केवल मूल्य है, तो यह पूरी तरह से संगत है।जब तक आप एक कुंजी का मान प्राप्त करते हैं, तब तक शब्दकोश में कुंजी का मूल्य बदल सकता है। यह डेटटाइम.अब मान के रूप में असंगत है। –

2

हाँ, आप सही हैं।

और उस धागे पर इसे बदलने के दौरान एक धागे पर शब्दकोश को गिनने की संभावना है कि उस वर्ग के अस्तित्व का एकमात्र साधन है।

+7

जो मैं जोड़ना चाहता हूं वह यह है कि [यहां] (http://blogs.msdn.com/b/pfxteam/archive/2010/01/08/9945809.aspx) उपयोगी जानकारी है कि कैसे और कब उपयोग करें ' ConcurrentDictionary'। –

1

इसे खोजने का सबसे अच्छा तरीका एमएसडीएन दस्तावेज की जांच है।

ConcurrentDictionary के लिए पेज http://msdn.microsoft.com/en-us/library/dd287191.aspx

धागा सुरक्षा खंड के अंतर्गत

है, यह कहा गया है "ConcurrentDictionary (TKey से TValue) के सभी सार्वजनिक और संरक्षित सदस्यों धागा सुरक्षित हैं और एक से अधिक थ्रेड से समवर्ती इस्तेमाल किया जा सकता है।"

तो समेकन बिंदु से आप ठीक हैं।

0

यह मेरे मामले में, मैं इस विधि का उपयोग करना पसंद करता हूं।

ConcurrentDictionary<TKey, TValue>.AddOrUpdate Method (TKey, Func<TKey, TValue>, Func<TKey, TValue, TValue>); 

विधि उपयोग विवरण के लिए MSDN Library देखें।

नमूना उपयोग:

results.AddOrUpdate(
    Id, 
    id => new DbResult() { 
    Id = id, 
    Value = row.Value, 
    Rank = 1 
    }, 
    (id, v) => 
    { 
    v.Rank++; 
    return v; 
    }); 
+1

एफवाईआई: "जब आप एक वैल्यू फैक्ट्री विधि (GetOrAdd और AddOrUpdate विधियों के लिए) की आपूर्ति करते हैं, तो यह वास्तव में चल सकता है और इसके परिणाम बाद में त्याग दिया जा सकता है (क्योंकि कुछ अन्य धागे ने दौड़ जीती थी)।" यहां अधिक जानकारी: https://arbel.net/2013/02/03/best-practices-for-using-concurrentdictionary/ – keremispirli

+0

हां, आप सही हैं, क्योंकि यह टिप्पणी अनुभाग में नोट किया गया है "यदि आप एक साथ AddOrUpdate को कॉल करते हैं विभिन्न धागे पर, addValueFactory को कई बार कहा जा सकता है, लेकिन इसकी कुंजी/मूल्य जोड़ी प्रत्येक कॉल के लिए शब्दकोश में नहीं जोड़ा जा सकता है। " तो आपको यह सुनिश्चित करने की ज़रूरत है कि आप कई लगातार वस्तुओं को उत्पन्न नहीं कर रहे हैं। – Onur

+0

और यदि आपको सामग्री को अद्यतन करने की आवश्यकता है, तो संग्रहित ऑब्जेक्ट को पूरी तरह से नहीं बदला जा रहा है, उदाहरण के लिए पहले जोड़े गए ऑब्जेक्ट की संपत्ति को बदलने के लिए, यह विधि उपयोगी है, अन्यथा आपको ताले या अन्य सिंक्रनाइज़ेशन विधियों का उपयोग करने की आवश्यकता है। – Onur

संबंधित मुद्दे