2011-02-23 21 views
11

में COM के माध्यम से पूछे गए इंटरफेस पर रिलीज कॉम ऑब्जेक्ट मैं सी # और DirectShow.Net का उपयोग कर डिजिटल टीवी (डीवीबी-टी) खेलने के लिए कुछ डायरेक्टशो इंटरफेस के साथ काम कर रहा हूं।मुझे मार्शल को कॉल करने की आवश्यकता है। सी #

_guideData = _transportInformationFilter as IGuideData;

_transportInformationFilter प्रकार IBaseFilter, पहले एक DirectShow.Net उपयोगिता समारोह के माध्यम से सौंपा एक COM ऑब्जेक्ट की है: मैं हाल ही में रनटाइम त्रुटि COM object that has been separated from its underlying RCW cannot be used.

निम्न पंक्ति में यह त्रुटि हुई का सामना करना पड़ा।

मैं मान लिया त्रुटि की वजह से किसी भी तरह _transportInformationFilter समय से पहले ही जारी किया जा रहा था, और मैं इसे निम्न विधि का पता लगाया (त्रुटि हटाया हैंडलिंग):

private void AttachGuideDataEvent() 
{ 
    IConnectionPoint connPoint = null; 
    IConnectionPointContainer connPointContainer = null; 
    try 
    { 
     connPointContainer = _transportInformationFilter as IConnectionPointContainer; 
     if (connPointContainer == null) /* error */ 

     var guideDataEventGuid = typeof (IGuideDataEvent).GUID; 
     connPointContainer.FindConnectionPoint(ref guideDataEventGuid, out connPoint); 
     if (connPoint == null) /* error */ 

     int cookie; 
     connPoint.Advise(this, out cookie); 
     if (cookie == 0) /* error */  
     _persistIGuideDataEventCookie = cookie; 
    } 
    finally 
    { 
     if (connPointContainer != null) 
      Marshal.ReleaseComObject(connPointContainer); 
     if (connPoint != null) 
      Marshal.ReleaseComObject(connPoint); 
    } 
} 

जैसा कि मैंने यह समझा, connPointContainer = _transportInformationFilter as IConnectionPointContainer कॉल में बदल जाना चाहिए था पर _transportInformationFilter COM ऑब्जेक्ट पर, और इस प्रकार अलग से रिलीज़ होने की आवश्यकता होगी। हालांकि, Marshal.ReleaseComObject(connPointContainer) पर कॉल अपराधी था जिसने _transportInformationFilter को अपने आरसीडब्ल्यू से अलग किया; इस कॉल को हटाने से समस्या ठीक हो गई।

यह देखते हुए, मुझे लीकिंग संसाधनों से बचने के लिए सी # में स्पष्ट रूप से COM ऑब्जेक्ट्स (Marshal.ReleaseComObject का उपयोग करके) को स्पष्ट रूप से रिलीज़ करने की आवश्यकता है?

उत्तर

10

लगभग कभी नहीं। रिलीजकॉम ऑब्जेक्ट आरसीडब्ल्यू की संदर्भ संख्या का प्रबंधन करता है, अंतर्निहित वस्तु नहीं है और सीधे IUnknown.Release के समान नहीं है। आपको सीएलआर को QueryInterface 'आईएनजी और Release' आईएनजी प्रबंधित करना चाहिए।

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

...

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

से http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.releasecomobject.aspx

FYI करें, जिस तरह से IUnknown.Release कॉल करने के लिए सीधे Marshal.Release, नहीं ReleaseComObject है।

+0

जानकारी के लिए धन्यवाद। यदि एमएसडीएन दस्तावेज़ कहते हैं कि कॉलर विशेष रूप से एक लौटा इंटरफ़ेस जारी करने के लिए ज़िम्मेदार है (उदाहरण के लिए http://msdn.microsoft.com/en-us/library/ms692476(VS.85).aspx), रनटाइम कॉल का प्रबंधन करेगा ऑब्जेक्ट दायरे से बाहर होने पर मेरे लिए रिलीज करने के लिए, या यह एक स्थिति है कि मुझे रिलीजकॉम ऑब्जेक्ट का उपयोग करना चाहिए? – jeffora

+0

वैसे यह तब काम नहीं करता जब ऑब्जेक्ट "दायरे से बाहर हो जाता है" लेकिन जब आरसीडब्ल्यू के लिए फाइनलर चलता है, तो कॉनपॉइंट के मामले में, यह चोट नहीं पहुंचाता है। ध्यान में रखना महत्वपूर्ण बात यह है कि 'रिलीजकॉम ऑब्जेक्ट' आरसीडब्लू पर चल रहा है, यह 'निपटान' को कॉल करने जैसा है, और यह इसी कारणों से टूट गया है कि '_ = _member IFoo के रूप में; a.Dispose(); _member.DoSomething() 'तोड़ सकता है। –

+0

प्रतिक्रिया के लिए बहुत बहुत धन्यवाद, समझ में आता है। – jeffora

2

मुझे लगता है कि मुझे मार्शल.ReleaseComObject का उपयोग करने के लिए वास्तव में वैध परिस्थिति मिली है। ExcelDNA का उपयोग कर सी # में एक्सेल एडिन लिखते समय, मैं वर्कर थ्रेड से COM इंटरऑप का उपयोग करता हूं, और एक्सेल ऑटोमेशन ऑब्जेक्ट्स जैसे "एप्लिकेशन", "वर्कबुक" इत्यादि का उपयोग करता हूं।

यदि मैं इन वस्तुओं को अंतिम रूप देने के लिए कचरा कलेक्टर के लिए इंतजार कर रहा था, तो मेरे पास एक्सेल से बाहर निकलने के बाद टास्क मैनेजर में एक अदृश्य एक्सेल "ज़ोंबी" उदाहरण शेष होगा। ऐसा इसलिए है क्योंकि उन आरसीडब्ल्यू जीवित उत्कृष्टता रखते हैं, और वे काफी समय तक चल सकते हैं।

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

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