[c#] मुझे सी # में "उपयोग" ब्लॉक का उपयोग कब करना चाहिए?


6 Answers

कुछ वस्तुओं को आपके साथ समाप्त होने पर कुछ कार्रवाई करने की आवश्यकता होती है। आम तौर पर ऐसा इसलिए होता है क्योंकि वस्तु किसी प्रकार के संसाधन का उपयोग करती है जिसे निपटाने की आवश्यकता होती है। उदाहरण के लिए, यदि आपके पास क्लास फ़ाइल का फ़ाइल ऑब्जेक्ट है, और यह ऑब्जेक्ट फ़ाइल सिस्टम से एक फ़ाइल खोलता है, तो फाइल सिस्टम में फ़ाइल को फिर से बंद करने की आवश्यकता होगी।

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

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

इस समस्या को हल करने के लिए सी # ने 'उपयोग' कीवर्ड पेश किया। आप एक 'ऑब्जेक्ट' कीवर्ड डाल सकते हैं जहां आप ऑब्जेक्ट को नया करते हैं, और यह सुनिश्चित करता है कि निपटान आपके लिए भी बुलाया जाएगा। यह गारंटी देता है कि निपटान को जो भी होता है उसे बुलाया जाएगा ... भले ही उपयोग कथन के शरीर में कोई अपवाद डाला गया हो।

इसलिए, जब आप यह सुनिश्चित करना चाहते हैं कि संसाधनों को आवंटित करने वाला ऑब्जेक्ट साफ़ किया जाएगा, तो आपको 'उपयोग' का उपयोग करना चाहिए।

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

सामान्य वस्तुओं को जिन्हें उन पर बुलाए जाने की आवश्यकता है वे हैं: फ़ाइलें, डेटाबेस कनेक्शन, ग्राफिक्स ऑब्जेक्ट्स जैसे पेन और ब्रश।

कभी-कभी इसका उपयोग तब भी किया जाता है जब आप दो संचालन एक साथ होने की इच्छा रखते हैं। उदाहरण के लिए यदि आप एक लॉग स्टेटमेंट लिखना चाहते हैं, जब कोड का एक ब्लॉक दर्ज किया जाता है और जब यह निकलता है तो आप एक लॉग क्लास लिख सकते हैं जिसे आप इस तरह उपयोग कर सकते हैं:

using( Log log = new Log("Doing stuff") )
{
    // Stuff
}

लॉग क्लास के लिए कन्स्ट्रक्टर संदेश लिखने के लिए बनाया जा सकता है, और निपटान विधि इसे भी लिख सकती है। अंतिमकरण (~ लॉग) को लागू करने के लिए लागू करें कि 'उपयोग' को 'नए लॉग' के आसपास याद रखने के लिए निपटान विधि को कॉल नहीं किया जाता है।

Question

इस प्रश्न का उत्तर यहां दिया गया है:

क्या ऐसे कुछ उदाहरण हैं जहां मुझे "उपयोग" ब्लॉक का उपयोग करना चाहिए (या नहीं?)

using(SomeType t = new SomeType()){
    ...
}



प्राथमिक नियम है: * ऑब्जेक्टिव इंटरफेस लागू करते समय ऑब्जेक्ट स्टेटमेंट का उपयोग करें।

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

यह बहुत महत्वपूर्ण है कि सभी संसाधन जो अब उपयोग में नहीं हैं, जितनी जल्दी हो सके मुक्त हो जाएं।

इसके बारे में अधिक जानकारी के लिए बस इस लिंक पर जाएं: microsoft




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

यदि यह एक List<T> कहने के साथ एक सामान्य वस्तु है, जहां टी एक Customer ऑब्जेक्ट की तरह है जिसमें नाम और पता है, तो आपको इसकी आवश्यकता नहीं है। कचरा कलेक्टर आपके लिए इसे प्रबंधित करने के लिए पर्याप्त स्मार्ट है। लेकिन कचरा कलेक्टर कनेक्शन पूल या करीबी फाइल हैंडल से कनेक्शन वापस नहीं करेगा।




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

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




मुझे लगता है कि जब आपके पास using कथन होना चाहिए तो कई अन्य उत्तरों संकेत दिए गए हैं। मैं विशेष रूप से using कथन नहीं होने पर पता करना चाहता हूं:

यदि आपको वर्तमान कार्य के दायरे से बाहर अपनी वस्तु का उपयोग करने की आवश्यकता है, तो इसका using ब्लॉक नहीं है। अच्छा उदाहरण एक फैक्ट्री विधि है जो डेटाबेस कनेक्शन या एक विधि देता है जिसे एक डाटाएडर वापस करने की आवश्यकता होती है। उन मामलों में से किसी एक मामले में यदि आप अपनी ऑब्जेक्ट को एक using कथन के साथ बनाते हैं तो इसे वापस आने वाली विधि से पहले निपटान किया जाएगा, और इसलिए विधि के बाहर प्रयोग योग्य नहीं है।

अब, आप अभी भी यह सुनिश्चित करना चाहते हैं कि उन वस्तुओं का निपटारा किया गया है, इसलिए आप अभी भी एक using कथन कहीं भी चाहते हैं। बस उस विधि में शामिल न करें जहां वस्तु वास्तव में बनाई गई है। इसके बजाए, आप फ़ंक्शन कॉल को स्वयं एक using कथन में लपेट सकते हैं।




उदाहरण:

        using(SqlConnection MyConnection = new SqlConnection("Connection string"))
        {
            MyConnection.Open();

            //...

            // 1. SQLConnection is a type that implements IDisposable
            // 2. So you can use MyConnection in a using statement
            // 3. When using block finishes, it calls Dispose method of 
            // SqlConnection class
            // 4. In this case, it will probably close the connection to 
            // the database and dispose MyConnection object

        }

आप अपनी खुद की वस्तुओं को बना सकते हैं जो IDISposable लागू करता है:

public class MyOwnObjectThatImplementsIDisposable : IDisposable
{

    //... some code

    public void Dispose()
    {
        // Put here the code you want to be executed when the
        // using statement finish.
    }
}

तो आप एक उपयोग कथन में MyOwnObjectThanImplementsIDisposable प्रकार की एक वस्तु का उपयोग कर सकते हैं:

        using(MyOwnObjectThatImplementsIDisposable MyObject = new MyOwnObjectThatImplementsIDisposable)
        {

            // When the statement finishes, it calls the 
            // code you´ve writed in Dispose method
            // of MyOwnObjectThatImplementsIDisposable class
        }

उम्मीद है की यह मदद करेगा




एक विशिष्ट उदाहरण जिसमें आपको using ब्लॉक का using करके सावधान रहना चाहिए, डब्ल्यूसीएफ सेवा क्लाइंट के साथ है

जैसा कि msdn.microsoft.com/en-us/library/aa355056.aspx में उल्लेख किया गया है, एक using ब्लॉक में डब्ल्यूसीएफ क्लाइंट (जो IDisposable लागू करता है) को लपेट सकता है, किसी भी त्रुटि को मुखौटा कर सकता है जिसके परिणामस्वरूप क्लाइंट को दोषपूर्ण स्थिति (जैसे टाइमआउट या संचार समस्या) में छोड़ा जा सकता है। लंबी कहानी छोटी, जब Dispose() कहा जाता है, क्लाइंट की Close() विधि आग लगती है, लेकिन फेंकती है और त्रुटि होती है क्योंकि यह एक दोषपूर्ण स्थिति में है। मूल अपवाद को फिर दूसरे अपवाद से मुखौटा किया जाता है। अच्छा नही।

वहाँ एमएसडीएन लेख में से एक सहित कई अलग-अलग कामकाज हैं। अन्य IServiceOriented और blog.davidbarret.net पर पाए जा सकते हैं।

मैं खुद को आखिरी विधि पसंद करता हूं।




Related



Tags

c# c#   .net .net   using