2012-07-23 20 views
7

में रनटाइम पर गतिशील ताले बनाना इस कोड के लिए निम्नलिखित मान्यताओं मान्य हैं? मैंने कोड के तहत कुछ पृष्ठभूमि जानकारी डाली, लेकिन मुझे नहीं लगता कि यह प्रासंगिक है।ASP.NET

अनुमान 1: चूंकि यह एक ही एप्लीकेशन है, इसलिए मैं धारणा कर रहा हूं कि इसे एक ही प्रक्रिया द्वारा संभाला जाएगा। इस प्रकार, स्थिर चर धागे के बीच साझा किए जाते हैं, और लॉक ऑब्जेक्ट्स का मेरा संग्रह स्थिर रूप से मान्य है।

अनुमान 2: यदि मुझे पता है कि मूल्य पहले से ही शब्दकोश में है, तो मुझे पढ़ने पर लॉक करने की आवश्यकता नहीं है। मैं एक ConcurrentDictionary का उपयोग कर सकता हूं, लेकिन मेरा मानना ​​है कि यह सुरक्षित होगा क्योंकि मैं गणना नहीं कर रहा हूं (या हटा रहा हूं), और मान मौजूद होगा और जब मैं UnlockOnValue() पर कॉल करता हूं तो नहीं बदलेगा।

अनुमान 3: मैं कुंजी संग्रह को लॉक कर सकता हूं, क्योंकि उस संदर्भ में परिवर्तन नहीं होगा, भले ही अंतर्निहित डेटा संरचना करता है।

private static Dictionary<String,Object> LockList = 
    new Dictionary<string,object>(); 

private void LockOnValue(String queryStringValue) 
{ 
    lock(LockList.Keys) 
    { 
     if(!LockList.Keys.Contains(queryStringValue)) 
     { 
      LockList.Add(screenName,new Object()); 
     } 
     System.Threading.Monitor.Enter(LockList[queryStringValue]); 
    } 
} 

private void UnlockOnValue(String queryStringValue) 
{ 
    System.Threading.Monitor.Exit(LockList[queryStringValue]); 
} 

तब मैं की तरह इस कोड का प्रयोग करेंगे:

LockOnValue(Request.QueryString["foo"]) 
//Check cache expiry 
//if expired 
    //Load new values and cache them. 
//else 
    //Load cached values 
UnlockOnValue(Request.QueryString["foo"]) 

पृष्ठभूमि: मुझे लगता है कि प्रश्न में एक भी उपयोगकर्ता परिभाषित चर के आधार पर डाउनलोड डेटा ASP.NET में एक ऐप्लिकेशन बना रहा हूं स्ट्रिंग। मूल्यों की संख्या काफी सीमित होगी। मुझे निर्दिष्ट अवधि के लिए प्रत्येक मान के परिणामों को कैश करने की आवश्यकता है।

दृष्टिकोण: मैंने डेटा को कैश करने के लिए स्थानीय फ़ाइलों का उपयोग करने का निर्णय लिया, जो कि सबसे अच्छा विकल्प नहीं है, लेकिन मैं इसे आजमा देना चाहता था क्योंकि यह गैर-महत्वपूर्ण है और प्रदर्शन एक बड़ा मुद्दा नहीं है। मैंने प्रति विकल्प 2 फाइलों का उपयोग किया, एक कैश समाप्ति तिथि के साथ, और डेटा के साथ एक।

समस्या: मुझे यकीन नहीं है कि लॉकिंग करने का सबसे अच्छा तरीका क्या है, और मैं .NET में थ्रेडिंग समस्याओं से अधिक परिचित नहीं हूं (कारणों में से एक कारण मैंने इस दृष्टिकोण को चुना है)। जो उपलब्ध है, और जो मैंने पढ़ा है, उसके आधार पर, मैंने सोचा कि उपरोक्त काम करना चाहिए, लेकिन मुझे यकीन नहीं है और दूसरी राय चाहिए।

+1

'HttpRuntime.Cache' का उपयोग करने में क्या समस्या है? – scottm

+0

यह मेरी पहली पसंद थी, लेकिन यह अजीब अभिनय कर रहा था। ऐसा इसलिए हो सकता है क्योंकि मेरा पृष्ठ प्रतिक्रिया को मिटा देता है और एक टेक्स्ट फ़ाइल देता है, लेकिन मैंने सभी इंटरनेट पर पोस्ट किए गए समान मुद्दों में भाग लेने के बाद बहुत गहराई से खोला नहीं है, मेरे लिए कोई जवाब नहीं है। आईआईएस कॉन्फ़िगरेशन में एकमात्र चीज नहीं आई थी और कैशिंग को सही तरीके से कॉन्फ़िगर किया गया था या नहीं। मैं अभी भी बाद में ऐसा कर सकता हूं, लेकिन यह ऐसा गैर-महत्वपूर्ण कोड है और यह उठाए गए प्रश्न हैं जिन्हें मैं जवाब देना चाहता था, भले ही यह सर्वोत्तम वास्तुकला न हो। – Kendrick

+0

मैं आपके लिए एक बहुत ही समान समाधान लागू करने की कोशिश कर रहा हूं जहां मैं कैशिंग विधियों के परिणाम देख रहा हूं। मुझे अलग-अलग कैश ताले बनाने का भी एक तरीका चाहिए और मैं सोच रहा था कि क्या आपके समाधान ने समय, चीयर्स के परीक्षण को रोक दिया है। –

उत्तर

6

आपका वर्तमान समाधान बहुत अच्छा दिखता है। दो चीजें जो मैं बदलूंगा:

1: अनलॉकऑनवेल्यू को आखिरकार ब्लॉक में जाना होगा। अगर कोई अपवाद फेंक दिया जाता है, तो यह कभी भी अपना लॉक जारी नहीं करेगा।

2: लॉकऑनवेल्यू कुछ हद तक अक्षम है, क्योंकि यह दो बार एक शब्दकोश लुकअप करता है।यह एक छोटे से शब्दकोश के लिए एक बड़ा सौदा नहीं है, लेकिन एक बड़े के लिए आप TryGetValue पर स्विच करना चाहेंगे।

इसके अलावा, आपकी धारणा 3 में कम से कम अभी तक है। लेकिन शब्दकोश अनुबंध कोई गारंटी नहीं देता है कि कुंजी संपत्ति हमेशा एक ही ऑब्जेक्ट लौटाती है। और चूंकि इस पर भरोसा करना इतना आसान नहीं है, इसलिए मैं इसके खिलाफ अनुशंसा करता हूं। जब भी मुझे लॉक करने के लिए किसी वस्तु की आवश्यकता होती है, तो मैं केवल उस उद्देश्य के लिए एक वस्तु बना देता हूं। कुछ ऐसा:

private static Object _lock = new Object(); 
+0

मुझे यह निर्दिष्ट करना चाहिए कि छद्म कोड में, लेकिन मेरे पास अंततः ब्लॉक में है। मैंने TryGetValue के बारे में कभी सोचा नहीं, लेकिन शायद यह एक बेहतर विकल्प है। शब्दकोश छोटा होगा, लेकिन अभी भी सोचना अच्छा होगा। – Kendrick

+0

हाँ, यह एक पालतू शिखर है जिसमें कॉल करने के लिए कॉल किया गया है और फिर एक कॉल [] क्योंकि उन्हें दोनों को तत्व ढूंढना है। – bmm6o

1

lock केवल एक ही प्रक्रिया का दायरा है। यदि आप प्रक्रियाओं को विस्तारित करना चाहते हैं तो आपको Mutex (नामित) जैसे प्राइमेटिव का उपयोग करना होगा।

lockMonitor.Enter और Monitor.Exit जैसा ही है। यदि आप Monitor.Enter और Monitor.Exit भी करते हैं, तो यह अनावश्यक है।

आपको पढ़ने पर लॉक करने की आवश्यकता नहीं है, लेकिन आपको यह जांचने के "लेनदेन" को लॉक करना होगा कि क्या मान मौजूद नहीं है और इसे जोड़ रहा है। यदि आप निर्देशों की उस श्रृंखला को लॉक नहीं करते हैं, तो जब आप कुंजी की जांच करते हैं और जब आप इसे जोड़ते हैं और इसे जोड़ते हैं तो कुछ और हो सकता है - इस प्रकार अपवाद होता है। जो लॉक आप कर रहे हैं वह करने के लिए पर्याप्त है (आपको एंटर करने और निकालने के लिए अतिरिक्त कॉल की आवश्यकता नहीं है - लॉक आपके लिए ऐसा करेगा)।

+0

मुझे लगता है कि इस एप्लिकेशन के लिए सभी थ्रेड एक ही प्रक्रिया से आ रहे हैं। दस्तावेज और उदाहरण मैंने इस बात पर ध्यान दिया है कि यह मामला है, हालांकि मैं अभी भी 100% निश्चित नहीं हूं। यह वास्तव में मेरी दूसरी धारणा है जिसके बारे में मुझे वास्तव में यकीन नहीं है। मुझे लगता है कि पहला सही है, और तीसरा शायद सही है, लेकिन शब्दकोश के लिए लॉक ऑब्जेक्ट बनाने के लिए ऐसा करने का कोई कारण नहीं है (यानी काम कर सकता है, लेकिन शायद खराब कोड) – Kendrick

+0

यदि यह एक एप्लीकेशन है और सभी थ्रेड हैं प्रक्रिया के एक उदाहरण में, लॉक उस स्थिति को फिट करता है। –