मेरे पास कई मामले हैं जहां मैं मूल्यों के कैशिंग के लिए ConcurrentDictionary<TKey, TValue>
का उपयोग करता हूं, लेकिन अक्सर यह तय करने के लिए कि मुझे ConcurrentDictionary<TKey, TValue>.GetOrAdd(TKey, Func<TKey, TValue>)
का उपयोग करके कैश में जोड़ना है या नहीं, यह मानने के लिए मूल्य की सत्यापन करने की आवश्यकता है।मैं मूल्य जोड़ने के लिए 'ConcurrentDictionary.GetOrAdd` कैसे कह सकता हूं?
:
private readonly ConcurrentDictionary<Type, ISomeObject> someObjectCache =
new ConcurrentDictionary<Type, ISomeObject>();
public ISomeObject CreateSomeObject(Type someType)
{
return someObjectCache.GetOrAdd(someType, type =>
{
if(!Attribute.IsDefined(someType, typeof(SomeAttribute))
// Do something here to avoid the instance from being added to
// `someObjectCache`
ISomeObject someObject;
// Typical factory functionality goes here
return someObject;
});
}
तरह से मैं संभाल यह आज एक अपवाद ठीक काम करने के लिए प्रकट होता है जो फेंकने के लिए है, लेकिन मैं एक क्लीनर दृष्टिकोण (शायद एक झंडा मैं सेट कर सकते हैं करना चाहते हैं या एक विशिष्ट मूल्य मैं वापसी मूल्य को सेट कर सकता हूं) GetOrAdd
को लैम्ब्डा के भीतर से रद्द करने के लिए (हालांकि इसे यथार्थ रूप से पूर्ण उड़ा विधि द्वारा प्रतिस्थापित किया जा सकता है)।
अन्य LINQ जैसे विधियों के साथ अपने अनुभव के आधार पर, null
लौटने के परिणामस्वरूप मूल्य को बिना जांच किए जोड़ा जा सकता है (और GetOrAdd
के लिए आईएल पढ़ना ऐसा लगता है कि यह एक ही समस्या का परिणाम देगा), इसलिए मैं ऐसा मत सोचो कि काम करेगा।
क्या कोई तरीका है कि मैं GetOrAdd
का उपयोग करके एड को रद्द करने के अपवादों का उपयोग करने से बच सकता हूं?
यह (और _I have_) होगा, लेकिन एक बार जब आप अव्यवस्थित हो जाएंगे कि सभी आवश्यक थ्रेड लॉकिंग तंत्र के साथ, यह बदसूरत हो जाता है (नहीं कि मुझे लॉकिंग की आवश्यकता नहीं है ... बस एक ही हद तक नहीं)। मैं एक क्लीनर समाधान की तलाश में हूं, ऐसा नहीं है जिसके लिए प्रभावी रूप से 'ConcurrentDictionary' के अपने संस्करण को रोल करने की आवश्यकता है। –
मेरा उत्तर अपडेट किया गया - GetOrAdd केवल आंतरिक सरणी बिट्स से निपटने के लिए, भाग को लॉक नहीं करता है। इसलिए, जैसा कि मैंने इसे देखा है, आपको यहां किसी भी ताले की आवश्यकता नहीं है यदि आपका इरादा केवल सत्यापन जोड़ना है। –
हां, मैंने दस्तावेज़ों के उस हिस्से को पढ़ लिया है, लेकिन यह अभी भी वह नहीं है जिसे मैं ढूंढ रहा हूं। अगर मैं इतना कोड लिखना चाहता था तो मैं खुद को लॉक कर दूंगा। –