2010-03-15 11 views
9

क्या तरीकों सी # में एक्सेल COM इंटरॉप वस्तुओं को नष्ट करने के लिए इन के अलावा हैं,:मैं सी # में COM ऑब्जेक्ट्स को कैसे नष्ट कर सकता हूं?

object_instance = null; 
System.GC.collect(); 
& 
System.Runtime.InteropServices.Marshal.ReleaseComObject(object); 

कृपया केवल इनबिल्ट तकनीक, bigcannon की तरह नहीं अन्य उपकरण, आदि

+2

आपको क्यों आवश्यकता है - ज्यादातर मामलों में, ढांचे को आपके लिए इसका ख्याल रखना चाहिए? – Paddy

+3

object_instance = null; रास्ते से वस्तु को नष्ट नहीं करता है। यह भी सुनिश्चित नहीं करता है कि यह कचरा एकत्रित होगा (यानी, क्योंकि कुछ और अभी भी इसका संदर्भ रख सकता है) –

+0

मुझे अपने एक्सेल प्रोग्राम में समस्या हो रही है जहां अवांछित वस्तु नियमित रूप से पैदा हो रही है, आप खोज के बाद "स्किंटिलेशन" कह सकते हैं एक स्ट्रिंग – perilbrain

उत्तर

17

किकर यह है कि यदि आपने ऑब्जेक्ट के सभी संदर्भों को भी नहीं छोड़ा है, तो भी जीसी। चयन इसे नष्ट नहीं करेगा।

सी # (या सामान्यतः .NET) में नियम यह है कि आप किसी ऑब्जेक्ट को नष्ट नहीं कर सकते हैं। निपटान() यह नहीं करेगा। एक फाइनलाइज़र ऐसा नहीं करेगा (नियम संख्या 2, फाइनलइज़र का उपयोग न करें जबतक कि आपको पता न हो कि आपको इसकी आवश्यकता क्यों है, और इसे कभी भी कॉल न करें)।

नेट के लिए, इन बातों को आप क्या करने की जरूरत है: एक वस्तु अप्रबंधित वस्तुओं के लिए संदर्भ रखती

  1. हैं, को लागू IDispose पैटर्न। और इसे पूरी तरह कार्यान्वित करें; यह केवल एक निपटान() विधि प्रदान करने से अधिक है।
  2. एकमात्र कारण होने का एकमात्र कारण अप्रबंधित वस्तुओं को छोड़ना है, और केवल उस स्थिति में जब आपकी ऑब्जेक्ट ठीक से निपटान नहीं की गई हो। एक बार आपकी निपटान विधि कहने के बाद, इसे क्लीनअप करना चाहिए, फिर GC.SuppressFinalize को कॉल करके फाइनलज़र को "मार दें"।
  3. यदि आप किसी ऑब्जेक्ट का उपयोग कर रहे हैं जो एक निपटान() विधि लागू करता है, तो उस ऑब्जेक्ट के साथ निष्पादित() को कॉल करें। सर्वोत्तम अभ्यास प्रैक्टिस ब्लॉक के साथ उस ऑब्जेक्ट को आवंटित करना है। उपयोग ब्लॉक से बाहर निकलें स्वचालित रूप से निपटान() को कॉल करेगा।
  4. जब आप किसी ऑब्जेक्ट के साथ होते हैं, तो ईवेंट हैंडलर, प्रतिनिधि इत्यादि सहित ऑब्जेक्ट के सभी संदर्भ ड्रॉप करें।
  5. इसके अलावा, कचरा कलेक्टर को अपना काम करने पर भरोसा करें। कचरा कलेक्टर के साथ गड़बड़ मत करो; आप केवल चीजों को और खराब करने की संभावना रखते हैं, जब तक कि आप वास्तव में वास्तव में नहीं जानते कि आप क्या कर रहे हैं और क्यों।
+0

+1 - अच्छा जवाब! मैं संसाधनों को शामिल करने के लिए # 1 योग्यता प्राप्त करूंगा। यदि आपकी कक्षा किसी प्रबंधित ऑब्जेक्ट का संदर्भ रखती है जो IDISpose लागू करती है, तो आप निपटान पैटर्न को भी कार्यान्वित करना चाहते हैं। आम तौर पर वह डिस्पोजेबल क्लास सीमित या महंगी बाहरी संसाधन का प्रतिनिधित्व करेगी। – TrueWill

+0

@ ट्राउविल, अच्छी सलाह। धन्यवाद। –

+0

मार्शल के बारे में क्या। ReleaseComObject? –

15

कचरा कलेक्टर केवल तंत्र है का सुझाव जो प्रबंधित ऑब्जेक्ट को नष्ट कर सकता है, लेकिन आप आमतौर पर इसे स्पष्ट रूप से नहीं बुलाते हैं। आप बस इसे अपनी बात करते हैं।

जैसे कि आप कभी भी डिपो में अपना कचरा नहीं लेते हैं, तो आप इसे कोने पर बैठकर छोड़ दें। यह हमेशा कचरा आदमी की ज़िम्मेदारी है।

आप चीजों के संदर्भ जारी कर सकते हैं और उन्हें IDISposable, फ़ाइनलाइजर्स और विनाशकों के साथ साफ कर सकते हैं लेकिन उन्हें नष्ट नहीं कर सकते हैं।

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

+0

(इंटरफ़ेस नाम को पूरा किया - आशा है कि आपको कोई फर्क नहीं पड़ता) –

+0

बिलकुल नहीं, लेकिन मैं मध्य-संपादन था, गलती से इसे नष्ट कर दिया लेकिन इसे वापस रख दिया। –

+0

कुछ कैस हैं जहां आपको वस्तु को स्पष्ट रूप से हटाने की आवश्यकता है ....... हालांकि मैं आपको अपना प्रोग्राम दिखाने में सक्षम नहीं हूं लेकिन आपको आश्वस्त कर सकता हूं कि मुझे वास्तव में वस्तु को नष्ट करने की आवश्यकता है .. – perilbrain

0

यदि आपका ऑब्जेक्ट महत्वपूर्ण संसाधन आवंटित करता है, तो IDISposable को लागू करना और स्पष्ट रूप से निपटान करना सबसे अच्छा है। यदि आप किसी कारण से निपटान नहीं कर सकते हैं और आपकी कक्षा अप्रबंधित स्मृति को सुरक्षित रखती है, तो आप जीसी को बता सकते हैं कि GC.AddMemoryPressure (अंतिम मिलान में GC.RemoveMemoryPressure मिलान करने के साथ) जीसी को बताएं कि आपकी कक्षा पहले से पहले की तुलना में भारी है, इसे पहले प्राथमिकता दें साफ - सफाई।

2

अधिकांश भाग के लिए, आपको किसी ऑब्जेक्ट के सभी संदर्भों को हटाना होगा। तभी कचरा कलेक्टर इसे देखेगा और इसे नष्ट कर देगा।

इस बात का ध्यान रखें

:

object_instance = null; 

यह सब करता है object_instance संदर्भ मारने है। यह काम करता है अगर यह एकमात्र संदर्भ है। यदि अन्य संदर्भ हैं, तो यह एकत्र नहीं किया जाएगा।

var skywalker = new Person(); 
var object_instance = skywalker; 

...

object_instance = null; 
//It's still alive and won't be collected because skywalker lives... 
0

तुम सच में स्पष्ट रूप से स्मृति एक वस्तु के कब्जे में रिक्त करने की आवश्यकता है, और आप, तो सुनिश्चित करें कि आप इसे जीसी की तुलना में बेहतर विनाश करने के लिए इस समय का चयन करेंगे कर रहे हैं केवल उचित विकल्प इसे स्टैक पर आवंटित करना है और इसे आवंटित करने के तरीके से वापस आने पर इसे मरने दें।

0

यदि आप नियंत्रण चाहते हैं ताकि आप ऑब्जेक्ट के संसाधनों का प्रबंधन कर सकें, फिर IDISposable इंटरफ़ेस को कार्यान्वित करें।

http://msdn.microsoft.com/en-us/library/system.idisposable.aspx

तो संसाधनों कारण है कि आप स्पष्ट रूप से वस्तु विनाश को नियंत्रित करने के, मैं नहीं जान सकता कि क्यों आप नियंत्रण के उस स्तर चाहते हैं नहीं कर रहे हैं ... आप वस्तु पूलिंग उपयोग करते हैं?

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