मैं एक थ्रेड-सुरक्षित विधि लिखने का प्रयास कर रहा हूं जिसे केवल एक बार (प्रति ऑब्जेक्ट इंस्टेंस) कहा जा सकता है। यदि इसे पहले कहा गया है तो एक अपवाद फेंक दिया जाना चाहिए।कैसे करें: एक थ्रेड-सुरक्षित विधि लिखें जिसे केवल एक बार बुलाया जा सकता है?
मैं दो समाधान के साथ आया हूं। क्या वे दोनों सही हैं? यदि नहीं, तो उनके साथ क्या गलत है?
lock
साथ :public void Foo() { lock (fooLock) { if (fooCalled) throw new InvalidOperationException(); fooCalled = true; } … } private object fooLock = new object(); private bool fooCalled;
Interlocked.CompareExchange
के साथ:public void Foo() { if (Interlocked.CompareExchange(ref fooCalled, 1, 0) == 1) throw new InvalidOperationException(); … } private int fooCalled;
अगर मैं गलत नहीं हूँ, इस समाधान ताला मुक्त होने का लाभ (है जो मेरे मामले में अप्रासंगिक लगता है), और इसके लिए कम निजी क्षेत्रों की आवश्यकता है ।
मैं उचित विचारों के लिए भी खुला हूं कि समाधान को प्राथमिकता दी जानी चाहिए, और यदि कोई बेहतर तरीका है तो आगे के सुझावों के लिए।
जिज्ञासा से बाहर: जब आप कहते हैं कि यह "कम जटिल" है, तो आप अंधेरे के पीछे चल रहे सभी चीजों का उल्लेख करते हैं; औसत प्रोग्रामर के लिए 'इंटरलाक्ड। एक्सचेंज कॉम्पारेयर' निर्माण की समझने की आसानी/आसानी से आप कैसे निर्णय लेंगे? – stakx
@stakx: यही टिप्पणियां हैं। जब एक प्रोग्रामर कुछ मुठभेड़ करता है जिसे वे समझ में नहीं आता है, तो उन्हें इसे देखना चाहिए ताकि वे इसे समझ सकें। इस तरह वे एक बेहतर प्रोग्रामर बन जाते हैं। – thecoop
@thecoop मैं असहमत हूं, हां यह सबसे सही समाधान है, लेकिन यह आसान नहीं है, आपको परमाणु संचालन आदि के बारे में जानना आवश्यक है। यह किसी भी तरह की प्रारंभिक प्रक्रिया है और मैं प्रारंभिक पैटर्न का पालन करने की सलाह दूंगा जो व्यापक रूप से उपयोग किए जाते हैं (जैसे डबल चेक लॉक)। इसके अलावा ये पैटर्न आपको कुछ खोने से रोकते हैं जो थ्रेडिंग करते समय आसानी से हो सकता है। – ntziolis