2008-10-28 12 views
8

यहां मुख्य समस्या है: मेरे पास एक .NET एप्लिकेशन है जो एक अलग ऐपडोमेन में COM interop का उपयोग कर रहा है। COM सामान एपडॉमेन के बजाय असेंबली को डिफ़ॉल्ट डोमेन में वापस लोड कर रहा है, जिससे COM सामान कहलाया जा रहा है।क्या COM इंटरऑप असेंबली लोडिंग के लिए .NET AppDomain सीमाओं का समर्थन करता है?

मैं क्या जानना चाहता हूं: क्या यह अपेक्षित व्यवहार है, या क्या मैं गलत COMDomain में इन COM संबंधित असेंबली को लोड करने के लिए कुछ गलत कर रहा हूं? कृपया नीचे दी गई स्थिति का अधिक विस्तृत विवरण देखें ...

एप्लिकेशन में 3 असेंबली शामिल हैं: - मुख्य EXE, एप्लिकेशन का प्रवेश बिंदु। - common.dll, जिसमें केवल एक इंटरफ़ेस आईकंट्रोलर (IPlugin शैली में) - controler.dll है, जिसमें नियंत्रक वर्ग है जो IController और MarshalByRefObject लागू करता है। यह वर्ग सभी काम करता है और किसी अन्य एप्लिकेशन के साथ बातचीत करने के लिए COM इंटरऑप का उपयोग करता है।

मुख्य EXE की प्रासंगिकता का इस तरह दिखता है:

AppDomain controller_domain = AppDomain.CreateDomain("Controller Domain"); 
IController c = (IController)controller_domain.CreateInstanceFromAndUnwrap("controller.dll", "MyNamespace.Controller"); 
result = c.Run(); 
AppDomain.Unload(controller_domain); 

common.dll केवल इन 2 बातें शामिल हैं:

public enum ControllerRunResult{FatalError, Finished, NonFatalError, NotRun} 
public interface IController 
{ 
    ControllerRunResult Run(); 
} 

और controller.dll इस वर्ग में शामिल है (जो भी COM इंटरऑप सामग्री को कॉल करता है):

public class Controller: IController, MarshalByRefObject 

जब पहली बार एप्लिकेशन चलाते हैं, Assembly.GetAssem blies() अपेक्षा के रूप में दिखता है, Common.dll दोनों AppDomains में लोड किया जा रहा है, और controler.dll केवल नियंत्रक डोमेन में लोड किया जा रहा है। c.Run कॉल करने के बाद() लेकिन मुझे लगता है कि COM इंटरॉप सामान से संबंधित विधानसभाओं AppDomain जहाँ से COM इंटरॉप हो रहा है में नहीं डिफ़ॉल्ट AppDomain में लोड किया गया है, और।

ऐसा क्यों हो सकता है?

और अगर आप रुचि रखते हैं, यहाँ पृष्ठभूमि का एक सा है:

मूल रूप से यह एक 1 AppDomain आवेदन किया गया था। COM सामान जो इंटरफेस करता है वह एक सर्वर एपीआई है जो लंबे समय तक उपयोग में स्थिर नहीं है। जब एक कॉमेक्सप्शन (इसके कारण के रूप में कोई उपयोगी नैदानिक ​​जानकारी नहीं है) COM सामान से होती है, तो COM कनेक्शन फिर से काम करने से पहले पूरे एप्लिकेशन को पुनरारंभ करना होगा। तत्काल COM अपवादों में बस COM ऐप सर्वर परिणामों से पुनः कनेक्ट हो रहा है। इसका सामना करने के लिए मैंने COM इंटरऑप सामान को एक अलग ऐपडोमेन में स्थानांतरित करने का प्रयास किया है ताकि जब रहस्य कॉमेक्सप्सेप्शन हो, तो मैं ऐपडोमेन को अनलोड कर सकता हूं जिसमें यह होता है, एक नया बनाएं और फिर से शुरू करें, बिना एप्लिकेशन को मैन्युअल रूप से पुनरारंभ किए बिना । वैसे भी सिद्धांत था ...

+0

fyi, अगर कोई और इसे देखता है - यह एचपी गुणवत्ता केंद्र एपीआई डीएलएल मुझे यह मुद्दा दे रहा है। मैंने ऐप को फिर से शुरू करके इसे चारों ओर काम किया, लेकिन मुझे अभी भी वास्तव में दिलचस्पी होगी कि यह क्यों हो रहा था। – Xiaofu

उत्तर

16

दुर्भाग्य से, एक COM घटक प्रक्रिया अंतरिक्ष के भीतर और एक AppDomain के संदर्भ में नहीं भरी हुई है। इस प्रकार, आपको अपने मूल DLL मैन्युअल रूप से आंसू (रिलीज़ और अनलोड) की आवश्यकता होगी (COM और P/Invoke दोनों पर लागू होता है)। बस एक appdomain को नष्ट आप अच्छा नहीं करेंगे, लेकिन पूरी प्रक्रिया respawning (COM राज्य पुनर्स्थापित करने के लिए बस COM वस्तु (रों पुनः बनाने के लिए आवश्यक नहीं होना चाहिए) भी सामान्य रूप से काम करना चाहिए, इस घटक प्रदाताओं कोड के भीतर एक बग की तरह लगता है, शायद वे इसे संबोधित कर सकते हैं?)

संदर्भ

(TechNet) Process Address Space

(MSDN) Application Domains

(MSDN) Boundaries: Processes and AppDomains

+0

आपकी प्रतिक्रिया के लिए धन्यवाद, शॉन। अब इतना लंबा रहा है कि अगर मैं COM वस्तुओं को पुनर्जीवित करने की कोशिश करता हूं तो मुझे याद नहीं है, लेकिन मुझे संदेह है कि मैंने किया था। जब मेरे पास समय होता है तो मैं आपके सुझावों को आज़मा दूंगा। इस बीच, प्रक्रिया स्थान का उल्लेख करने के लिए +1। – Xiaofu

+0

इसलिए मुझे अभी भी इसे आजमाने का मौका नहीं मिला है, लेकिन आपने वास्तव में मुख्य प्रश्न का उत्तर दिया है, इसलिए मैं इसे उत्तर के रूप में चिह्नित करूंगा। हर किसी के इनपुट के लिए बहुत धन्यवाद। – Xiaofu

+0

और हां, मुझे संदेह है कि यह प्रदाता के कोड में एक बग है, खासतौर पर त्रुटि के कारण के रूप में मुझे COM घटक को पुनः लोड/अनलोड/पुनः लोड करना एक असली रहस्य है। हालांकि किसी और को दोष देने से पहले मुझे किसी दिन फिर से अपना कोड दोबारा जांचना चाहिए। – Xiaofu

0

अपने नियंत्रक एमबीआर मत बनाओ। एक छोटा प्रॉक्सी बनाएं, जो दूसरे डोमेन में नियंत्रक लोड करता है और इसे शुरू करता है। इस तरह नियंत्रक डीएल पहले डोमेन में लोड नहीं किया जाएगा।

+0

हाय सनी, यह एक सामान्य डीएल में आईकंट्रोलर इंटरफेस का उपयोग करने के पीछे विचार था। Controller.dll को डिफ़ॉल्ट डोमेन में लोड नहीं किया जाता है। नियंत्रक डोमेन में नियंत्रक वर्ग द्वारा COM इंटरऑप गतिविधि डिफ़ॉल्ट डोमेन में COM से संबंधित DLL लोड होने का कारण बनती है। – Xiaofu

+0

अद्यतन: अन्य डोमेन में नियंत्रक बनाने और चलाने के लिए प्रॉक्सी का उपयोग करना एक ही प्रभाव है। Controller.dll डिफ़ॉल्ट AppDomain (जो समस्या नहीं थी) में लोड नहीं हो रहा है, लेकिन COM इंटरऑप सामान अभी भी डिफ़ॉल्ट डोमेन में COM असेंबली लोड हो रहा है। – Xiaofu

+0

क्या आपने दूसरे डोमेन में मैन्युअल रूप से इंटरऑप असेंबली लोड करने का प्रयास किया था, और ऑटोलोडर पर रिले नहीं किया था? –

2

यहाँ सबूत है कि शॉन विल्सन के जवाब सही है

Com App Domain

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