2009-01-21 16 views
14

यह है कि मैं क्या "सी # के माध्यम से CLR" से IDisposable और finalizers के बारे में समझना है, "प्रभावी सी #" और अन्य संसाधनों:finalizer साथ सिंगलटन लेकिन IDisposable नहीं

  • IDisposable को साफ करने में कामयाब रहे और अप्रबंधित संसाधनों निर्धारणात्मक के लिए है।
  • अप्रबंधित संसाधनों (जैसे फ़ाइल हैंडल) के लिए ज़िम्मेदार वर्गों को IDISposable लागू करना चाहिए और यह गारंटी देने के लिए एक अंतिमकर्ता प्रदान करना चाहिए कि क्लाइंट कोड उदाहरण पर निपटान() को कॉल नहीं करता है, भले ही वे साफ़ हो जाएं।
  • प्रबंधित संसाधनों के लिए ज़िम्मेदार वर्ग केवल अंतिमकरण को लागू नहीं करना चाहिए।
  • यदि आपके पास फाइनेंजर है तो आपको IDISposable लागू करना होगा (यह क्लाइंट कोड को सही चीज़ करने और निपटान() को कॉल करने की अनुमति देता है, जबकि अंतिमकर्ता संसाधन भूलने से रोकता है)। एक सिंगलटन वर्ग कि अप्रबंधित संसाधनों (जैसे केवल एक प्रदान करने के रूप के लिए जिम्मेदार है:

जब मैं तर्क के लिए और ऊपर के सभी के साथ सहमत समझते हैं, वहाँ एक परिदृश्य में जहाँ मुझे लगता है कि यह समझ में आता है इन नियमों को तोड़ने के लिए है विशेष फाइलों तक पहुंच का बिंदु)।

मेरा मानना ​​है कि सिंगलटन पर एक डिस्प्ले() विधि हमेशा गलत है क्योंकि सिंगलटन इंस्टेंस एप्लिकेशन के जीवन के लिए जीना चाहिए और यदि कोई क्लाइंट कोड कॉल() को कॉल करता है तो आप भरे हुए हैं। हालांकि, आप एक फाइनलाइज़र चाहते हैं ताकि जब एप्लिकेशन को अनलोड किया जाए तो फाइनलाइज़र अप्रबंधित संसाधनों को साफ कर सकता है।

तो एक फाइनेंजर के साथ सिंगलटन क्लास होने पर IDISposable को लागू नहीं किया जाता है, ऐसा लगता है कि मुझे ऐसा करने के लिए एक उचित चीज है, फिर भी इस प्रकार का डिज़ाइन जो मैं समझता हूं उसके विपरीत है।

क्या यह एक उचित दृष्टिकोण है? यदि नहीं, तो क्यों नहीं और बेहतर विकल्प क्या हैं?

उत्तर

3

यदि अप्रबंधित संसाधन केवल एप्लिकेशन से बाहर निकलने पर जारी किया जाता है तो आपको अंतिम निर्माता के साथ चिंता करने की भी आवश्यकता नहीं होती है क्योंकि प्रक्रिया अनलोड को आपके लिए इसके साथ सौदा करना चाहिए।

यदि आपके पास एकाधिक ऐप डोमेन हैं और आप एक ऐप डोमेन से निपटना चाहते हैं तो यह एक संभावित समस्या है, लेकिन संभवतः आपको इसकी परवाह करने की आवश्यकता नहीं है।

मैं दूसरा कह रही है कि इस डिजाइन संभवतः नहीं करना सही बात है (और यह कठिन ठीक करने के लिए कर देगा है बाद में आप पाते हैं कि आप वास्तव में दो उदाहरणों की आवश्यकता है) है उन वस्तु (या एक आलसी लोड हो रहा है आवरण वस्तु बनाएं) अपने प्रवेश बिंदु में और इसे कोड के माध्यम से पास करें जहां यह आवश्यक है कि इसे स्पष्ट करने के लिए कौन जिम्मेदार है, तो आप शेष कोड के लिए केवल थोड़ा प्रभाव के साथ केवल एक का उपयोग करने के निर्णय को बदलने के लिए स्वतंत्र हैं (का उपयोग करता है जो यह क्या दिया जाता है)

4

मैं पहले उल्लेख करता हूं कि ऑब्जेक्ट ओरिएंटेड डिज़ाइन पैटर्न और उनके परिणाम ऑब्जेक्ट ओरिएंटेड भाषाओं में भी हर भाषा निर्णय को प्रभावित नहीं करते हैं। आप निश्चित रूप से क्लासिक डिज़ाइन पैटर्न ढूंढ सकते हैं जो एक भाषा (स्मॉलटाक) में लागू करने के लिए आसान हैं (सी ++)।

कहा जा रहा है, मुझे यकीन नहीं है कि मैं इस आधार पर सहमत हूं कि एक सिंगलटन उदाहरण केवल एक आवेदन के अंत में निपटाया जाना चाहिए। Singleton (या Design Patterns: Elements of reusable Object-Oriented Software) के लिए मैंने जो डिज़ाइन पैटर्न विवरण पढ़े हैं, उनमें से कुछ भी इस पैटर्न की संपत्ति के रूप में इसका उल्लेख नहीं करता है। एक सिंगलटन को यह सुनिश्चित करना चाहिए कि कक्षा में केवल एक ही समय किसी भी क्षण में मौजूद है; यह इस बात का तात्पर्य नहीं है कि जब तक एप्लिकेशन मौजूद है तब तक यह अस्तित्व में होना चाहिए।

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

दूसरे शब्दों में, आप परिदृश्य बना सकते हैं जहां सिंगलटन के लिए यह महत्वपूर्ण है कि यह IDISposable है।

+1

तथ्य यह है कि यदि आप ऐप के जीवनकाल के दौरान अपनी ऑब्जेक्ट को प्रतिस्थापित करने का कोई कारण समझ सकते हैं, तो ऑब्जेक्ट वैध रूप से सिंगलटन नहीं हो सकता है। क्यों के लिए ... कहो मैंने सिंगलटन को पकड़ लिया और इसे उस सामान में पास कर दिया जिसकी आवश्यकता थी (कारण, पता है, निर्भरता इंजेक्शन एक अच्छी बात है)। फिर कहीं कुछ इसे बदलने का फैसला करता है। अब * दो सिंगलेट * हैं (पुराना मैं चारों ओर गुजर रहा हूं, और नया)। यह संभावना सिंगलटन की पूरी परिभाषा का उल्लंघन करती है - यानी, वह कोड हमेशा एक उदाहरण को देखता है। – cHao

+0

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

+2

यदि ऑब्जेक्ट का निपटारा किया गया है, तो उदाहरण * * अभी भी मौजूद है - जो भी इसे पहले हासिल कर लेता था, उसे अभी भी प्राप्त किया जाएगा। तो यह स्पष्ट रूप से जीसीड नहीं हो सकता है, लेकिन अब यह अनुपयोगी है। एक बहुप्रचारित संदर्भ में उस कथन के परिणामों के बारे में सोचें। 'Singleton.getInstance()। DoStuff() 'जैसी अभिव्यक्ति अब थ्रेड सुरक्षित नहीं है, * भले ही' getInstance' और 'doStuff' दोनों * हैं। दो कॉल के बीच एक धागा आ सकता है और हमने जो उदाहरण हासिल किया है उसका निपटान कर सकते हैं। और यह भी आपके पौराणिक सभी को मानता है-हमेशा-कॉल-'getInstance' परिदृश्य। स्थिर वर्ग के लिए – cHao

3

जब तक आपका अंतिमकर्ता किसी भी अन्य प्रबंधित वस्तुओं पर विधियों (जैसे निपटान) को कॉल नहीं करता है, तो आपको ठीक होना चाहिए। बस याद रखें कि अंतिमकरण आदेश निर्धारक नहीं है। यही कारण है, अगर आपके सिंगलटन वस्तु फू एक संदर्भ बार है कि निपटान की आवश्यकता आपत्ति उठाने रखती है, आप मज़बूती से नहीं लिख सकते हैं:

~Foo() 
{ 
    Bar.Dispose(); 
} 

कचरा कलेक्टर को पहले से ही बार एकत्र हो सकता है।

ओओ गुओ (यानी एक युद्ध शुरू करने) के ढेर में कदम उठाने के जोखिम पर, एक सिंगलटन का उपयोग करने का एक विकल्प एक स्थिर वर्ग का उपयोग करना है।

+0

+1 - सिंगलटन आवश्यक नहीं हैं क्योंकि उनकी सर्वव्यापीता का सुझाव होगा। –

+0

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

+0

किस स्कॉट ने कहा - डिस्पोजेबल सिंगलेट्स केवल एक मौलिक समस्या है – annakata

2

हालांकि यह आपको कोड समीक्षा पकड़ और FxCop चेतावनियां प्राप्त कर सकता है, लेकिन बिना किसी IDISposable के फाइनल को कार्यान्वित करने में आंतरिक रूप से कुछ भी गलत नहीं है। हालांकि, एक सिंगलटन पर ऐसा करने से प्रक्रिया या ऐपडोमेन आंसू को पकड़ने का एक विश्वसनीय तरीका नहीं है।

व्यक्तिपरक डिजाइन सलाह देने के जोखिम पर: यदि वस्तु वास्तव में स्टेटलेस है, तो इसे एक स्थिर वर्ग बनाएं। यदि यह राज्यपूर्ण है, सवाल यह है कि यह सिंगलटन क्यों है: आप एक परिवर्तनीय वैश्विक चर बना रहे हैं। यदि आप एप्लिकेशन को बंद करने की कोशिश कर रहे हैं, तो जब आपका मुख्य पाश निकलता है तो उससे निपटें।

+0

"यदि वस्तु वास्तव में स्टेटलेस है, तो इसे एक स्थिर वर्ग बनाएं। यदि यह राज्यपूर्ण है, तो सवाल यह है कि यह सिंगलटन क्यों है" मैं पूरी तरह से सहमत हूं, लेकिन मुझे उद्धृत की तस्वीर पसंद है। इसके लिए एक संदर्भ मिला? – annakata

+0

मैंने इसे फ्लाई पर बनाया। मैं पोर्टलैंड पैटर्न रिपोजिटरी पर कुछ समय के लिए सिंगलेट्स के अधिकांश उपयोगों के खिलाफ रेलिंग कर रहा हूं क्योंकि कोड में कारणता पर उनके प्रभाव के कारण। –

0
एक तरफ किसी विशेष स्थिति के लिए सिंगलटन की

प्रयोज्यता,

मुझे लगता है कि एस के निपटान के साथ कुछ भी गलत नहीं है Ingleton। आलसी तात्कालिकता के संयोजन में इसका मतलब यह है कि यदि आप अस्थायी रूप से इसकी आवश्यकता नहीं है, तो संसाधन को छोड़ दें, और फिर आवश्यकतानुसार इसे पुनः प्राप्त करें।

+0

कोड का एक टुकड़ा अधिग्रहण कर सकता है और "निपटान" एक सिंगलटन कहता है कि कोई और भी इसका उपयोग कर रहा है या नहीं। अगर फाइनलर को बुलाया जाता है, तो कोई भी इसका उपयोग नहीं कर रहा है; ध्यान दें कि ऐसा होने का एकमात्र तरीका यह होगा कि सिंगलटन के स्थिर/वैश्विक संदर्भ एक कमजोर थे। अन्यथा यह संदर्भ खुद को सिंगलटन को अंतिम रूप देने से बचाएगा। – supercat

0

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

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