2008-09-29 20 views
224

.NET में, किस परिस्थितियों में मुझे GC.SuppressFinalize() का उपयोग करना चाहिए?मुझे GC.SuppressFinalize() का उपयोग कब करना चाहिए?

इस विधि का उपयोग करने से कौन सा लाभ (ओं) करता है?

+0

मैं finalizers और IDisposable बारे में कुछ प्रश्नों को देखा है, stackoverflow भी GC.SupressFinalize और कमजोर संदर्भों के बारे में कुछ करना चाहिए था –

+0

मैं कमजोर संदर्भ finalizers के बारे में कुछ भी ज्यादा कुछ नहीं लगता है - हो सकता है आप एक अधिक पोस्ट करना चाहिए उनके बारे में सीधा सवाल। –

+0

Yerp मैं कमजोर refs के बारे में एक अलग सवाल है, यह सब एक साथ बाँध सकते हैं जब आप वस्तु पूल बनाते पोस्ट करने के लिए अर्थ किया गया था। नहीं भी "चाहिए" - - इसके अलावा, मैं वस्तु पुनरुद्धार के बारे में एक सवाल ReRegisterForFinalize –

उत्तर

243

SuppressFinalize केवल उस वर्ग द्वारा बुलाया जाना चाहिए जिसमें अंतिमकर्ता है। यह कचरा कलेक्टर (जीसी) को सूचित कर रहा है कि this ऑब्जेक्ट पूरी तरह साफ हो गया था।

सिफारिश की IDisposable पैटर्न जब आप एक finalizer है:

public class MyClass : IDisposable 
{ 
    private bool disposed = false; 

    protected virtual void Dispose(bool disposing) 
    { 
     if (!disposed) 
     { 
      if (disposing) 
      { 
       // called via myClass.Dispose(). 
       // OK to use any private object references 
      } 
      // Release unmanaged resources. 
      // Set large fields to null.     
      disposed = true; 
     } 
    } 

    public void Dispose() // Implement IDisposable 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    ~MyClass() // the finalizer 
    { 
     Dispose(false); 
    } 
} 

आम तौर पर, CLR एक finalizer के साथ वस्तुओं पर नजर रखता है (बनाने उन्हें बनाने के लिए और अधिक महंगी) जब वे बनाए गए हैं। SuppressFinalize जीसी को बताता है कि ऑब्जेक्ट ठीक से साफ किया गया था और इसे अंतिम कतार में जाने की आवश्यकता नहीं है। यह एक सी ++ विनाशक की तरह दिखता है, लेकिन ऐसा कुछ भी नहीं करता है।

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

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

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

नोट: कभी-कभी कोडर अपने आईडीस्पोजेबल ऑब्जेक्ट को सही तरीके से निपटाते हुए परीक्षण करने के लिए अपने स्वयं के आईडीस्पोजेबल वर्गों के निर्माण को डीबग करने के लिए फाइनलर जोड़ देंगे।

public void Dispose() // Implement IDisposable 
    { 
     Dispose(true); 
    #if DEBUG 
     GC.SuppressFinalize(this); 
    #endif 
    } 

    #if DEBUG 
    ~MyClass() // the finalizer 
    { 
     Dispose(false); 
    } 
    #endif 
+0

मैं अपने कोड के साथ सहमत हैं, लेकिन मैं डिबग संस्करण में एक ज़ोर डाल ... और संसाधन निपटारा किया जा रहा है, तो था महंगा, मैं रिहाई verion में finalizer छोड़ना होगा। –

+1

पहले कोड स्निपेट में मैं सिर्फ पोस्टिंग कर रहा हूँ की सिफारिश की IDisposable + finalizer पैटर्न कैसा दिखता है। डीबगिंग कोड अच्छा है, लेकिन यह विचलित हो सकता है। .. मैं केवल उन्मूलन संसाधनों वाले वर्गों को छोड़कर अंतिमकर्ता से बचने की सिफारिश कर सकता हूं। सुरक्षित फाइनलाइज़र कोड लिखना गैर-तुच्छ है। –

+0

क्या मैं बेस क्लास में डिस्पोजेक्ट पैटर्न का उपयोग कर सकता हूं और इसे दूसरों के बीच बढ़ा सकता हूं? –

1

उस विधि को ऑब्जेक्ट्स लागू करने वाली ऑब्जेक्ट्स की डिस्प्ले विधि पर कॉल किया जाना चाहिए, इस तरह जीसी किसी अन्य समय को अंतिम बार कॉल नहीं करेगा अगर कोई व्यक्ति निपटान विधि को कॉल करता है।

देखें: http://msdn.microsoft.com/en-us/library/system.gc.suppressfinalize.aspx

+6

आला मुझे लगता है कि "चाहिए" गलत है पूछना चाहिए यह सिर्फ है कि कुछ स्थितियों में, आप कतार की भूमि के ऊपर/समाप्त कर सकते हैं वस्तु को अंतिम रूप देने के लिए। – Basic

29

आप प्रणाली है कि जो कुछ भी काम finalizer में किया गया है | कह रहे हैं पहले से ही किया गया है ताकि finalizer कहा जा की जरूरत नहीं है।

वस्तुओं कि IDisposable इंटरफ़ेस को लागू एक उद्देश्य यह है कि आवश्यकता नहीं है पर Object.Finalize कॉल करने से से इस विधि को IDisposable.Dispose विधि कचरा कलेक्टर को रोकने के कॉल कर सकते हैं: .NET डॉक्स से यह।

सामान्यतया, अधिकांश किसी भी निपटान() विधि, GC.SupressFinalize() कॉल करने के लिए है, क्योंकि यह सब कुछ है कि finalizer में Cleand किया जाएगा साफ करना चाहिए सक्षम होना चाहिए।

SupressFinalize केवल कुछ ऐसा है जो एक अनुकूलन प्रदान करता है जो सिस्टम को अंतिम उत्पाद धागे को ऑब्जेक्ट को कतार में परेशान नहीं करने देता है। एक उचित ढंग से लिखित निपटान()/फ़ाइनलाइज़र को GC.SupressFinalize() को कॉल के साथ या बिना ठीक से काम करना चाहिए।

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

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