2010-01-18 11 views
7

मैं माइक्रोसॉफ्ट.इंटर्रोप.एक्ससेल डीएलएल का उपयोग कर एक्सेल क्लास लिख रहा हूं। मैं सभी फ़ंक्शन समाप्त करता हूं लेकिन मुझे अपने विनाशक में एक त्रुटि है। मैं अपनी फाइल में सभी बदलावों को सहेजना चाहता हूं और मैं सभी स्रोतों को छोड़ना चाहता हूं। मैं उन सभी को अपने विनाशक में चाहता हूं। लेकिन मेरे विनाशक में, Excel.AplicationClass, वर्कबुक और वर्कशीट ऑब्जेक्ट्स एक अपवाद से भर जाते हैं जिसमें संदेश होता है "COM ऑब्जेक्ट जिसे इसके अंतर्निहित आरसीडब्ल्यू से अलग किया गया है, का उपयोग नहीं किया जा सकता है।" तो मैं कुछ भी नहीं बचा सकता, कुछ भी बंद नहीं कर सकता क्योंकि मैं कार्यपुस्तिका या वर्कशीट ऑब्जेक्ट तक नहीं पहुंच सकता।मेरे विनाशक में रिलीज एक्सेल ऑब्जेक्ट

क्या मैं विनाशक में कक्षा के निजी सदस्यों तक नहीं पहुंच सकता?

+0

यदि आप हमें अपनी कक्षाओं के बारे में कुछ और बताते हैं तो यह सहायक हो सकता है। जब विनाशक को बुलाया जाता है - जब आवेदन बंद हो जाता है या किसी अन्य उपयोगकर्ता द्वारा शुरू किए गए समय पर? – Ant

उत्तर

15

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

इस पर सबसे अच्छे लेखों में से एक Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework है। विशेष रूप से फाइनलाइजर्स पर अधिक जानकारी के लिए, एमएसडीएन में आलेख Finalize Methods and Destructors देखें।

क्या मैं विनाशक में निजी निजी सदस्यों तक पहुंच नहीं सकता?

नहीं, आप सुरक्षित रूप से ऐसा नहीं कर सकते हैं।

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

दिक्कत यह है कि न केवल करने के लिए जब इन वस्तुओं कचरा अनिश्चित एकत्र हो रहे हैं के रूप में समय है, लेकिन आदेश जिसमें finalizers कहा जाता है भी गैर नियतात्मक है। इस मामले में, एक रनटाइम कॉलबल रैपर में एक फाइनिज़र भी होता है, जो Marshal.ReleaseComObject पर स्वयं को कॉल करता है, जिसके बाड़ के COM पक्ष पर संदर्भ गणना में कमी का परिणाम होता है ताकि यह COM ऑब्जेक्ट जारी किया जा सके। लेकिन चूंकि अंतिम आदेशकर्ताओं को बुलाया जाने वाला आदेश अनिश्चित है, इसलिए यह बहुत संभव है कि COM के लिए फाइनल ऑब्जेक्ट्स आपके ऑब्जेक्ट संदर्भ आपके ऑब्जेक्ट के लिए अंतिमकर्ता से पहले आग लगेंगे।तो आपके फ़ाइनलाइज़र के भीतर कोड कभी-कभी काम कर सकता है, लेकिन, ज्यादातर समय, रनटाइम कॉलबल रैपर का एक या अधिक जो आपके ऑब्जेक्ट संदर्भों में पहले से ही उनके अंतिम नामक होते हैं, और अंतर्निहित COM ऑब्जेक्ट जारी किया जाएगा, पहले आपका फ़ाइनलाइज़र अपना कोड निष्पादित करता है।

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

अपने स्थिति में सुधार करने के लिए, मैं दो अलग अलग संभावनाओं पर विचार होगा:

  1. कॉम का निपटान एक ही विधि है कि उन्हें बनाता है के भीतर वस्तुओं। मेरे पास इस here और here पर कुछ चर्चाएं हैं।

  2. गैर-निर्धारिती अंतिमकर्ता पर भरोसा करने के बजाय IDisposable interface का उपयोग करके अपने ऑब्जेक्ट का निर्धारिक निपटान सक्षम करें।

कैसे IDisposable पैटर्न को लागू करने पर लेख के लिए देखें:

- माइक

0

नहीं, आपको किसी विनाशक में किसी भी प्रबंधित ऑब्जेक्ट तक नहीं पहुंचना चाहिए: इसमें COM RCW शामिल हैं।

इसके बजाय, मानक आईडीस्पोज़ेबल पैटर्न को कार्यान्वित करें, और अपनी COM ऑब्जेक्ट्स को डिस्प्ले (बूल) विधि में रिलीज़ करें जैसे कि आप एक डिस्पोजेबल प्रबंधित ऑब्जेक्ट करेंगे।

1

मुझे यकीन नहीं है कि क्या मैं कुछ गलत कोड कर रहा हूं - यहां उदाहरणों का पालन करने का प्रयास किया। मैंने पाया कि जब मैं IDISposable पैटर्न का लाभ उठाता हूं तब तक सबकुछ काम करता है जब तक कि मुझे कार्यपुस्तिका की घटनाओं को संभालने की आवश्यकता न हो।

मेरे परिदृश्य में उपयोगकर्ता ऐप बंद करने से पहले कार्यपुस्तिका को बंद कर सकता है। मैंने Excel ऑब्जेक्ट के साथ एवेन्ट्स घोषित कर दिया है और आवश्यकताओं को पूरा करने के लिए वर्कबुक से पहले हैंडलर को संभाला है।

इस परिदृश्य में मुझे "COM ऑब्जेक्ट जो इसके अंतर्निहित आरसीडब्ल्यू से अलग किया गया है, का उपयोग नहीं किया जा सकता" त्रुटि जब मैं अपना ऐप बंद करने के लिए जाता हूं (और मैंने एक्सेल को पहले ही बंद कर दिया है)। जब यह निपटान (गलत) कॉल करता है तो त्रुटि को अंतिम रूप में हो रहा है।

अगर मैं एक्सेल ऑब्जेक्ट को ईवेंट के साथ घोषित करता हूं तो समस्या दूर हो जाती है लेकिन किसी भी हैंडलर को कोड न करें।

मेरे निपटान में मुझे अपनी कार्यपुस्तिकाओं के लिए त्रुटि निगलनी पड़ी। बंद करें और छोड़ें क्योंकि वे बयान थे जो त्रुटि उत्पन्न करते थे।

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