2012-03-14 26 views
7

से COM जारी करें मान लें कि मेरे पास COM ऑब्जेक्ट (अप्रबंधित) और .NET क्लाइंट है।.NET और COM इंटरऑपरेबिलिटी: .NET क्लाइंट

क्या COM ऑब्जेक्ट को जारी करने के लिए .NET क्लाइंट Marshal.FinalReleaseComObject विधि से कॉल करना आवश्यक है?

+3

http://blogs.msdn.com/b/visualstudio/archive/2010/03/01/marshal-releasecomobject-cononsidered-dangerous.aspx –

+0

धन्यवाद - बहुत उपयोगी लेख –

उत्तर

2

नहीं। नेट क्लाइंट से COM ऑब्जेक्ट को स्पष्ट रूप से रिलीज़ करने की आवश्यकता नहीं है। COM ऑब्जेक्ट किसी भी अन्य .NET ऑब्जेक्ट की तरह एकत्र किया जाएगा और इसके सभी संदर्भ हटा दिए जाने के बाद इसे मूल अंतर्निहित देशी हैंडल जारी कर दिया जाएगा।

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

+0

जबकि "सिद्धांत में" कोई नहीं हो सकता है जरूरत है, "अभ्यास में", वहाँ * निश्चित रूप से * है। साथ ही, FinalReleaseComObject का उपयोग न करें, बल्कि प्रत्येक बार * COM ऑब्जेक्ट को COM-.NET सीमा पर लाया गया है * के लिए रिलीजकॉम ऑब्जेक्ट। मैं आउटलुक एडिन प्रोग्रामिंग करता हूं: और मैं कह सकता हूं, ऑब्जेक्ट्स देना * स्पष्ट जीवनकाल एक काम करने वाला ऐड-इन * बनाने का एकमात्र तरीका है। अवधि। (मैं एक सहायक/रैपर वर्ग का उपयोग करता हूं जो निपटान का समर्थन करता है मैं 'उपयोग' के साथ उपयोग करता हूं।) –

+3

गलत अभ्यास। आप जीसी। कोलेक्ट() + जीसी.WaitForPendingFinalizers() यदि आपको करना है, तो इसे कभी गलत नहीं मिलता है। –

+1

@ हंसपैसेंट जो Outlook ऑब्जेक्ट मॉडल के साथ काम नहीं करता है। विभिन्न संबंधित "समाधान" में एक पंक्ति में * अनुक्रम * दो बार * का आह्वान करने की कोशिश शामिल है। यह सिर्फ "अभ्यास में" काम नहीं करता है (जिन मामलों में मैं सौदा करता हूं)। –

2

संशोधित "हां" और "नहीं"।

पहले, मन में भालू है कि ReleaseComObjectस्वचालित रूप से वास्तविक COM वस्तु रेफरी गिनती नहीं कमी है। इसके बजाय यह आंतरिक आरसीडब्ल्यू काउंटर को कम करता है। (हर बार वही COM ऑब्जेक्ट COM-> नेट से स्थानांतरित हो जाता है, यह उसी आरसीडब्ल्यू का उपयोग करेगा और आरसीडब्लू काउंटर को एक से बढ़ाएगा।) इसी प्रकार, FinalRelaseComObject आरसीडब्ल्यू काउंटर और प्रभावी ढंग से "इसे 0 पर सेट करता है" को भी प्रभावित करता है। ऐसा तब होता है जब आरसीडब्ल्यू काउंटर शून्य हो जाता है कि .NET वास्तविक COM रेफ-गिनती घटाएगा।

तो, "हाँ", लेकिन इन नियमों के लिए संशोधित:

  1. हर बार कॉम से एक वस्तु पार> नेट यह चाहिए है ReleaseComObject, लेकिन नहींFinalReleaseComObject , इस पर आह्वान किया। यह है कि, एक बार को प्रत्येक बार ऑब्जेक्ट पार करने के लिए, को संदर्भित किया जाना चाहिए, भले ही इसका संदर्भ आरसीडब्ल्यू के बराबर हो।
  2. आरसीडब्ल्यू (जो सिर्फ एक प्रॉक्सी रैपर है) के संदर्भों की संख्या कोई फर्क नहीं पड़ता; केवल वस्तु ने सीमा पार कर लिया है। नियम # 1 देखें। (यह संदर्भ और जो उन्हें नियंत्रित करने के लिए रहता है महत्वपूर्ण है, लेकिन "सबसे बुरी" है कि इस मामले में क्या होता है एक "अलग RCW" जो एक निपटाई गई धारा का उपयोग करने से अलग नहीं है का उपयोग करने से एक अपवाद है।)

मैं कहता हूँ उपरोक्त नियमों और नहीं FinalReleaseComObject क्योंकि RCW वस्तुओं एक पहचान प्रॉक्सी में कैश नहीं किया जाता है, तो FinalReleaseComObjectका उपयोग कर नेट सीमा क्रॉसिंगों कॉम को प्रभावित करेगा> तुम भी के बारे में पता नहीं था! (यह बुरा है और, इस मुद्दे पर, मैं पूरी तरह से JaredPars जवाब के साथ सहमत हैं।)

और "नहीं" है कि में, एक RCW पुन: दावा किया जाता है जब (finalizer कहा जाता है), यह स्वतः ही होगा "रिलीज" COM संदर्भ (प्रभावी रूप से FinalReleaseComObject पर कॉल करें)। याद रखें कि चूंकि केवल एक आरसीडब्लू ऑब्जेक्ट है इसका मतलब है कि यह कभी भी को पुनः प्राप्त नहीं किया जाएगा जब तक कि .NET में इसका संदर्भ न हो।यदि आरसीडब्ल्यू पुनः दावा किया गया है तो कोई समस्या नहीं है क्योंकि, ऊपर से, आरसीडब्ल्यू के लिए कोई और संदर्भ नहीं हैं और इस प्रकार .NET जानता है कि यह एक द्वारा COM ref-count को कम कर सकता है (जो COM ऑब्जेक्ट को नष्ट कर सकता है) ।

हालांकि, चूंकि .NET जीसी परिष्कृत है और गैर-निर्धारिती है, इस व्यवहार पर निर्भर करने का अर्थ है कि वस्तु-जीवनकाल नियंत्रित नहीं होते हैं। उदाहरण के लिए, Outlook ऑब्जेक्ट मॉडल के साथ काम करते समय कई सूक्ष्म समस्याएं हो सकती हैं। (यह कम अन्य COM सर्वर के साथ मुद्दों होने का खतरा हो सकता है लेकिन यह OOM अजीब आंतरिक वस्तुओं की "कैशिंग" करता है। यह जब जीवन काल को स्पष्ट रूप से नियंत्रित नहीं एक "आइटम पहले से ही संशोधित किया गया है" अपवाद प्राप्त करने के लिए आसान है।)

मेरे कोड में मेरे पास ComWrapper कक्षा है जो IDisposable का समर्थन करती है। यह मुझे COM-> नेट से स्पष्ट जीवनकाल स्वामित्व के साथ प्राप्त आरसीडब्लू ऑब्जेक्ट्स पास करने की अनुमति देता है। इस दृष्टिकोण पर स्विच करने के बाद मेरे पास Outlook-Addin विकास में बहुत कम समस्याएं हैं (लगभग कोई नहीं, वास्तव में) और हाथ से पहले समस्याएं हैं। "नकारात्मक" यह है कि COM-> नेट सीमा को निर्धारित करने की आवश्यकता है, लेकिन एक बार ऐसा करने के बाद, आंतरिक रूप से सभी जीवनकाल सही ढंग से संभाले जाते हैं।

हैप्पी कोडिंग।

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

  • कोई संबंधित समस्या नहीं^_^