2011-10-18 13 views
5

मैं परंपरागत तरीके से IDisposable को संभालने के लिए तकनीक से अवगत हूं। कहो, OnStop() खिड़कियों सेवा की विधि में मैं बंद संदेश कतार ग्राहक:शून्य पर सेट करके निपटान?

 if (client != null) 
     { 
      client.Dispose(); 
     } 

पहली बार आज मैंने देखा कि एक पुरुष इस तरह से कर रही के लिए:

 using (client) 
     { 
      client = null; 
     } 

वास्तव में क्या हो रहा है उसके अंदर "प्रयोग" या क्या वह बिल्कुल सही तरीके से निपटता है?

उत्तर

4

आपका using-आधारित सहकर्मी का कोड काम करेगा, लेकिन तर्कसंगत रूप से अधिक है;

using(client) { 
    client = null; 
} 

अनिवार्य है:

{ // scope here to denote that 'tmp' is not defined outside this scope 
    var tmp = client; 
    try { 
     client = null; 
    } finally { 
     if(tmp != null) tmp.Dispose(); 
    } 
} 

(नहीं काफी कि सभी मामलों में, के रूप में देखते हैं मूल्य-प्रकार और स्पष्ट इंटरफेस कार्यान्वयन के बारे में सोचने के लिए)।

व्यक्तिगत रूप से, मैं संभवतः पूरी चीज के लिए using का उपयोग करूंगा (यानी उस कोड में जो प्रारंभ में क्लाइंट आवंटित करता है)।

using(client as IDisposable) { client = null; } // dispose if needed 

यानी client मेरे नियंत्रण से बाहर कुछ है, और मुझे यकीन है कि अगर यह IDisposable लागू करता है या नहीं नहीं कर रहा हूँ, लेकिन अगर यह होता है, मैं की जरूरत है:

एक बार मैं इस का उपयोग कर सकते एक आलसी है छोड़ दीजिए।

+0

बीटीडब्लू, एक बात जो मुझे लगता है कि "उपयोग" की उपयोगिता में वृद्धि होगी, स्पष्ट रूप से "छाया चर" को शून्य पर सेट करने की क्षमता होगी, ताकि ऑब्जेक्ट का निपटारा नहीं किया जा सके, या फिर "उपयोग" का एक संस्करण हो केवल गलती के मामले में निपटान करेगा। उदाहरण के लिए, एक कन्स्ट्रक्टर, ऑब्जेक्ट के फ़ील्ड का निर्माण करने के लिए "उपयोग" कर सकता है, और उसके बाद इसे वापस रखने से ठीक पहले "रखने" का फैसला कर सकता है। "उपयोग" के बजाय प्रयास/अंत में ब्लॉक का उपयोग करना संभव है, लेकिन वे अधिक verbose और कम स्पष्ट हैं। – supercat

+0

@supercat आईएमओ कि परिदृश्य पहले से ही जटिल है - इसके बारे में स्पष्ट होना बेहतर है, और समझ रहा है कि क्या हो रहा है (यानी मैं 'try' /' अंत में 'खुश हूं) –

+0

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

3

से

using (client) 
{ 
} 

client.Dispose() बाहर निकल रहा है आप के लिए स्वचालित रूप से कहा जाता है।
client = null को मेरी राय में उस कोड से बाहर बुलाया जाना चाहिए।
याद रखें कि using(object) का उपयोग करने के लिए ऑब्जेक्ट को IDisposable इंटरफ़ेस लागू करना चाहिए।

+2

क्यों डाउनवोट? मैंने कुछ गलत बताया, कृपया समझाएं ताकि मैं अपना जवाब सही या हटा सकूं ... – Marco

+0

नहीं, विशेष रूप से कुछ भी गलत नहीं है; एक उपयोगकर्ता द्वारा डाले गए कुछ अजीब डाउनवॉट्स थे; इस धागे में शामिल किसी भी उपयोगकर्ता को कोई मजबूत टाई नहीं। बस ... अजीब, वास्तव में। –

+0

धन्यवाद @MarcGravell, बस समझने के लिए और (अंत में) कुछ नया सीखें ... – Marco

6

using(){} कथन संदर्भ var की एक प्रति प्राप्त करता है इसलिए null के साथ यह असाइनमेंट अप्रभावी है।

+0

लेकिन हानिरहित (यह निपटाने के लिए कॉल में हस्तक्षेप नहीं करता है) – Martijn

+0

दूसरे मामले में सहमत हैं आपको एक बार फिर पॉइंटर कॉपी करना होगा। इसे निपटाने के अंदर अंतर्निहित निपटान करने का कोई मतलब नहीं है। किसी भी मामले में निपटान को पुन: पेश करते समय आपको शून्य अपवाद से बचने के लिए एक शून्य जांच की भी आवश्यकता है। –

+1

@Martijn - हानिरहित? आमतौर पर नहीं, लेकिन अगर आप 'क्लाइंट 'का निपटान स्थगित करना चाहते हैं। दुर्लभ लेकिन संभव है। –

0

मेरे लिए यह बिल्कुल प्रभावी नहीं दिखता है। चूंकि क्लाइंट का उपयोग करने के लिए सेट किया गया है, इसका उपयोग अब और भी निपटाने के लिए संदर्भित नहीं किया गया है, भले ही वास्तविक वस्तु अभी भी स्मृति में है, फिर भी किसी भी चर द्वारा संदर्भित नहीं किया गया है (यह कचरा बाद में एकत्र किया जाएगा, लेकिन तब उपयोग करने का क्या मतलब है?)।

0

यदि "क्लाइंट" का दायरा "उपयोग" ब्लॉक के बाहर फैला हुआ है, जैसा कि ऐसा प्रतीत होता है, लिखित कोड यह सुनिश्चित करेगा कि नियंत्रण से पहले "क्लाइंट" का निपटान किया जाता है, "ब्लॉक" का उपयोग छोड़ देता है, और संदर्भ नव-निष्क्रिय "क्लाइंट" ऑब्जेक्ट नष्ट हो जाएगा। इसके संदर्भ को बाहर करना महत्वपूर्ण हो सकता है यदि यह एक क्षेत्र है, और यह महत्वपूर्ण हो सकता है यदि यह ऐसी संपत्ति है जो घटनाओं को जोड़ती है।

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

 
    Zap(ref client); 

जो अधिक संक्षिप्त जा रहा है, जबकि लगभग निश्चित रूप से साफ किया जा रहा है को लाभ मिलता है: उस मामले में, "का उपयोग" बयान के साथ प्रतिस्थापित किया जाएगा।

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