खोज…


टिप्पणियों

  • यह सुनिश्चित करने के लिए कि वे ऑब्जेक्ट का उपयोग कर समाप्त होने पर Dispose विधि को कॉल IDisposable लिए IDisposable को लागू IDisposable वाले वर्ग के ग्राहकों पर निर्भर हैं। सीएलआर में ऐसा कुछ भी नहीं है जो सीधे वस्तुओं को खोज करने के लिए एक Dispose विधि के लिए खोजता है।

  • यह अंतिम रूप से लागू करने के लिए आवश्यक नहीं है यदि आपकी वस्तु में केवल प्रबंधित संसाधन हैं। जब आप अपनी स्वयं की Dispose विधि को लागू करते हैं, तो आपकी कक्षा द्वारा उपयोग की जाने वाली सभी वस्तुओं पर Dispose को कॉल करना सुनिश्चित करें।

  • Dispose करने के लिए कई कॉल के खिलाफ क्लास को सुरक्षित बनाने की सिफारिश की जाती है, हालांकि इसे आदर्श रूप में केवल एक बार बुलाया जाना चाहिए। यह आपकी कक्षा में एक private bool वैरिएबल जोड़कर और Dispose विधि के चलने पर मूल्य को true सेट करके प्राप्त किया जा सकता है।

एक ऐसे वर्ग में जिसमें केवल प्रबंधित संसाधन होते हैं

प्रबंधित संसाधन वे संसाधन हैं जो रनटाइम के कचरा संग्रहकर्ता को जानते हैं और नियंत्रण में हैं। उदाहरण के लिए, BCL में कई वर्ग उपलब्ध हैं, जैसे कि SqlConnection जो एक अप्रबंधित संसाधन के लिए एक आवरण वर्ग है। ये कक्षाएं पहले से ही IDisposable इंटरफ़ेस को लागू करती हैं - जब आप काम करते हैं तो उन्हें साफ करने के लिए यह आपके कोड पर निर्भर करता है।

यदि आपके वर्ग में केवल प्रबंधित संसाधन हैं, तो अंतिम रूप से लागू करना आवश्यक नहीं है।

public class ObjectWithManagedResourcesOnly : IDisposable
{
    private SqlConnection sqlConnection = new SqlConnection();

    public void Dispose()
    {
        sqlConnection.Dispose();
    }
}

प्रबंधित और अप्रबंधित संसाधनों के साथ एक वर्ग में

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

public class ManagedAndUnmanagedObject : IDisposable
{
    private SqlConnection sqlConnection = new SqlConnection();
    private UnmanagedHandle unmanagedHandle = Win32.SomeUnmanagedResource();
    private bool disposed;

    public void Dispose()
    {
        Dispose(true); // client called dispose
        GC.SuppressFinalize(this); // tell the GC to not execute the Finalizer
    }

    protected virtual void Dispose(bool disposeManaged)
    {
        if (!disposed)
        {
            if (disposeManaged)
            {
                if (sqlConnection != null)
                {
                    sqlConnection.Dispose();
                }
            }

            unmanagedHandle.Release();

            disposed = true;
        }
    }

    ~ManagedAndUnmanagedObject()
    {
        Dispose(false);
    }
}

IDis प्रयोज्य, निपटान

.NET फ्रेमवर्क एक आंसू-डाउन विधि की आवश्यकता के लिए एक इंटरफ़ेस को परिभाषित करता है:

public interface IDisposable
{
  void Dispose();
}

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

public void Dispose()
{
   if (null != this.CurrentDatabaseConnection)
   {
       this.CurrentDatabaseConnection.Dispose();
       this.CurrentDatabaseConnection = null;
   }
}

जब आपको अनवांटेड पॉइंट या win32 संसाधनों जैसे मानव रहित संसाधनों को सीधे एक्सेस करने की आवश्यकता होती है, तो SafeHandle से विरासत में मिली एक क्लास बनाएं और ऐसा करने के लिए उस क्लास के कन्वेंशन / टूल्स का उपयोग करें।

प्रबंधित संसाधनों के साथ एक विरासत वाले वर्ग में

यह काफी सामान्य है कि आप एक ऐसा वर्ग बना सकते हैं जो IDisposable लागू करता है, और फिर उन वर्गों को प्राप्त करता है जिनमें प्रबंधित संसाधन भी होते हैं। virtual कीवर्ड के साथ Dispose विधि को चिह्नित करने की सिफारिश की जाती है ताकि ग्राहकों के पास अपने स्वयं के संसाधनों को साफ करने की क्षमता हो।

public class Parent : IDisposable
{
    private ManagedResource parentManagedResource = new ManagedResource();

    public virtual void Dispose()
    {
        if (parentManagedResource != null)
        {
            parentManagedResource.Dispose();
        }
    }
}

public class Child : Parent
{
    private ManagedResource childManagedResource = new ManagedResource();

    public override void Dispose()
    {
        if (childManagedResource != null)
        {
            childManagedResource.Dispose();
        }
        //clean up the parent's resources
        base.Dispose();
    }
}

कीवर्ड का उपयोग करना

जब कोई वस्तु IDisposable इंटरफ़ेस को लागू करती है, तो इसे सिंटैक्स का using बनाया जा सकता है:

using (var foo = new Foo())
{
    // do foo stuff
} // when it reaches here foo.Dispose() will get called

public class Foo : IDisposable
{
    public void Dispose()
    {
        Console.WriteLine("dispose called");
    }
}

डेमो देखें

using एक try/finally ब्लॉक के लिए सिंथेटिक चीनी है ; उपरोक्त उपयोग मोटे तौर पर में अनुवाद करेगा:

{
    var foo = new Foo();
    try
    {
        // do foo stuff
    }
    finally
    {
        if (foo != null)
            ((IDisposable)foo).Dispose();
    }
}


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow