.NET में, मुझे किन परिस्थितियों में उपयोग करना चाहिए GC.SuppressFinalize()
?
इस पद्धति का उपयोग करने से मुझे क्या लाभ है?
.NET में, मुझे किन परिस्थितियों में उपयोग करना चाहिए GC.SuppressFinalize()
?
इस पद्धति का उपयोग करने से मुझे क्या लाभ है?
जवाबों:
SuppressFinalize
केवल एक वर्ग द्वारा बुलाया जाना चाहिए जिसमें एक अंतिम रूप है। यह कचरा संग्रहकर्ता (जीसी) को सूचित कर रहा है कि this
वस्तु को पूरी तरह से साफ किया गया था।
IDisposable
जब आपके पास अंतिम रूप हो तो अनुशंसित पैटर्न:
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);
}
}
आम तौर पर, सीएलआर वस्तुओं पर एक अंतिम रूप से नज़र रखता है जब वे बनाए जाते हैं (बनाने के लिए उन्हें अधिक महंगा बनाते हैं)। SuppressFinalize
जीसी को बताता है कि ऑब्जेक्ट को ठीक से साफ किया गया था और इसे अंतिम कतार पर जाने की आवश्यकता नहीं है। यह C ++ डिस्ट्रक्टर की तरह दिखता है, लेकिन यह किसी भी चीज की तरह काम नहीं करता है।
SuppressFinalize
अनुकूलन के रूप में अपने वस्तुओं एक लंबे समय finalizer कतार पर इंतजार कर रह सकते हैं, तुच्छ नहीं है। SuppressFinalize
अन्य वस्तुओं पर कॉल करने के लिए परीक्षा मत करो तुम मन। यह एक गंभीर दोष होने की प्रतीक्षा कर रहा है।
डिज़ाइन दिशानिर्देश हमें सूचित करते हैं कि यदि आपकी वस्तु लागू होती है IDisposable
, तो एक अंतिम रूप से आवश्यक नहीं है , लेकिन यदि आपके पास एक अंतिम उपकरण है तो आपको IDisposable
अपनी कक्षा के निर्धारक सफाई की अनुमति देने के लिए लागू करना चाहिए ।
अधिकांश समय आपको IDisposable
संसाधनों को साफ करने में सक्षम होना चाहिए । आपको केवल एक अंतिम रूप देने वाले की आवश्यकता होनी चाहिए जब आपकी वस्तु अप्रबंधित संसाधनों पर आधारित हो और आपको उन संसाधनों को साफ करने की गारंटी देने की आवश्यकता हो।
नोट: कभी-कभी कोडर अंतिम रूप से अपने स्वयं के IDisposable
वर्गों के डिबग बिल्ड में जोड़ देंगे ताकि यह परीक्षण किया जा सके कि कोड ने उनकी IDisposable
वस्तु को ठीक से निपटाया है।
public void Dispose() // Implement IDisposable
{
Dispose(true);
#if DEBUG
GC.SuppressFinalize(this);
#endif
}
#if DEBUG
~MyClass() // the finalizer
{
Dispose(false);
}
#endif
IDisposable
नहीं है sealed
, तो उसे कॉल को इसमें शामिल करना चाहिए, GC.SuppressFinalize(this)
भले ही उसमें उपयोगकर्ता द्वारा परिभाषित अंतिम रूप से शामिल न हो । यह व्युत्पन्न प्रकारों के लिए उचित शब्दार्थ सुनिश्चित करने के लिए आवश्यक है जो एक उपयोगकर्ता-परिभाषित फ़ाइनलीज़र जोड़ते हैं लेकिन केवल संरक्षित Dispose(bool)
विधि को ओवरराइड करते हैं ।
sealed
व्युत्पन्न वर्गों के लिए @SamHarwell द्वारा उल्लेख नहीं किया जाना महत्वपूर्ण है। कोडएनालिसिस का परिणाम ca1816 + ca1063 होता है जब कक्षा को सील नहीं किया जाता है, लेकिन सील की गई कक्षाएं बिना ठीक होती हैं SuppressFinalize
।
SupressFinalize
सिस्टम को बताता है कि फाइनल में जो भी काम किया जाएगा वह पहले ही हो चुका है, इसलिए फाइनल करने वाले को बुलाने की जरूरत नहीं है। .NET डॉक्स से:
वस्तुएं जो कि आइडीसोपायरी इंटरफ़ेस को लागू करती हैं, इस विधि को आईडीआईसोप्रेटी से कह सकते हैं। कचरा विधि से ऑब्जेक्ट को कॉल करने से रोकने के लिए विधि का उपयोग करें। ऐसी वस्तु पर जिसकी आवश्यकता नहीं होती है।
सामान्य तौर पर, किसी भी Dispose()
विधि को कॉल करने में सक्षम होना चाहिए GC.SupressFinalize()
, क्योंकि यह सब कुछ साफ करना चाहिए जो अंतिम रूप से साफ हो जाएगा।
SupressFinalize
बस कुछ ऐसा है जो एक अनुकूलन प्रदान करता है जो सिस्टम को अंतिम थ्रेड के लिए ऑब्जेक्ट को पंक्तिबद्ध नहीं करने की अनुमति देता है। एक ठीक से लिखा Dispose()
/ अंतिम रूप से एक कॉल के साथ या उसके बिना ठीक से काम करना चाहिए GC.SupressFinalize()
।
उस विधि को उन Dispose
वस्तुओं की विधि पर बुलाया जाना चाहिए जो IDisposable
इस तरह से लागू होती हैं , इस तरह जीसी अंतिम रूप से किसी अन्य समय कॉल नहीं करेगा यदि कोई Dispose
विधि को कॉल करता है।
देखें: GC.SuppressFinalize (ऑब्जेक्ट) विधि - Microsoft डॉक्स
Dispose(true);
GC.SuppressFinalize(this);
यदि ऑब्जेक्ट में अंतिम रूप है, तो .net ने अंतिम रूप से कतार में एक संदर्भ दिया।
चूंकि हमारे पास कॉल है Dispose(ture)
, यह स्पष्ट वस्तु है, इसलिए हमें इस काम को करने के लिए अंतिम रूप से कतार की आवश्यकता नहीं है।
तो GC.SuppressFinalize(this)
अंतिम संदर्भ कतार में कॉल निकालें संदर्भ।
एक वर्ग, या कुछ भी से व्युत्पन्न, एक finalizer के साथ एक वस्तु के लिए पिछले लाइव संदर्भ पैदा हो सकती हैं, तो या तो GC.SuppressFinalize(this)
या GC.KeepAlive(this)
किसी भी आपरेशन कि प्रतिकूल कि finalizer से प्रभावित हो सकता के बाद वस्तु पर बुलाया जाना चाहिए, इस प्रकार यह सुनिश्चित करना कि finalizer जीता जब तक कि ऑपरेशन पूरा नहीं हो जाता, तब तक नहीं चलेंगे।
की लागत GC.KeepAlive()
और GC.SuppressFinalize(this)
अनिवार्य रूप से किसी भी वर्ग में एक ही है कि एक अंतिम रूप नहीं है, और वर्गों है कि अंतिम रूप से आम तौर पर फोन करना चाहिए GC.SuppressFinalize(this)
, तो बाद के समारोह के रूप में अंतिम चरण का Dispose()
उपयोग करना हमेशा आवश्यक नहीं हो सकता है, लेकिन यह नहीं होगा गलत हो।