2010-10-17 14 views
5

मैं एक एक्सेल प्लग में (सी # में लिखा) एक स्थिर चर एक सिंगलटन डेटा कैश के मूल में है कि के साथ:एक्सेल दो अलग-अलग ऐपडोमेन से .NET स्वचालन सर्वर का आह्वान करता है?

static DataCache _instance; 

यह तीन अलग-अलग कोड रास्तों के माध्यम से पहुंचा जा सकता है:

    एक VSTO रिबन पट्टी पर
  1. घटना संचालकों उदाहरण प्रारंभ, और भी सहायक संवाद में प्रदर्शन के लिए इसे पढ़ा
  2. एक RTD सर्वर (एक वर्ग है कि [ComVisible] की घोषणा की और IRtdServer इंटरफ़ेस लागू करता है) डेटा का इस्तेमाल करता RTD सूत्रों के लिए
  3. ऑटोमेशन कॉल का एक सेट (घोषित किया गया एक और वर्ग में लागू [कॉमविज़िबल]) भी डेटा पर काम करता है। इन्हें वीबीए कोड के माध्यम से बुलाया जाता है जिसे एक्सेल वर्कशीट पर बटन क्लिक किए जाने पर बुलाया जाता है।

संपादित करें (# 3):

जिस क्रम में इन कोड रास्तों पहले लागू कर रहे हैं पर निर्भर करता है, मुझे लगता है कि मेरी कोड दो अलग-अलग AppDomains में चलाता है पाते हैं।

रिबन-बार ईवेंट हैंडलर से सभी पहुंच "MyPlugIn.vsto" नामक ऐपडोमेन में होती है। यदि यह मेरी COM ऑब्जेक्ट की पहली पहुंच है, तो सभी बाद की कॉल (आरटीडी कॉल सहित) एक ही ऐपडोमेन में होती है।

हालांकि अगर पहली पहुंच आरटीडी इंटरफ़ेस के माध्यम से होती है, तो वह कॉल और बाद में आरटीडी कॉल "DefaultDomain" नामक ऐपडोमेन में होती है। (यह तब होता है जब एम्बेडेड आरटीडी सूत्रों के साथ सहेजे गए दस्तावेज़ को लोड करते हैं।) टूलबार के माध्यम से डेटा कैश को प्रारंभ करने और कुशलतापूर्वक उपयोग करने के लिए बाद में कॉल "MyPlugIn.vsto" AppDomain में होती है। इसका मतलब है कि आरटीडी सूत्र हमेशा चलते हैं जैसे डेटा कैश प्रारंभ नहीं किया गया था (चूंकि एक ऐपडोमेन में स्थैतिक परिवर्तनीय सेट दूसरे में अनियंत्रित रहता है)।

ऐसा प्रतीत होता है कि एक्स्ट्रा या वीएसटीओ वीएसटीओ शुरू होने पर ऐपडोमेन बना रहा है। इस प्रारंभिकरण से पहले COM इंटरऑप के माध्यम से बनाए गए ऑब्जेक्ट्स डिफ़ॉल्ट AppDomain में भूमि, जबकि ऑब्जेक्ट्स बाद में VSTO AppDomain में भूमि बनाते हैं।

मैं कैसे सुनिश्चित कर सकता हूं कि उसी डेटा कैश उदाहरण का उपयोग किया जाता है, इससे कोई फर्क नहीं पड़ता कि मेरे आरटीडी सर्वर ऑब्जेक्ट में कौन सा ऐपडोमेन बनाया गया है?

+0

आपका क्या मतलब है 'मेरी सिंगलटन वस्तु ठीक से साझा नहीं कर रहा है'? क्या यह ऑब्जेक्ट का प्रारंभिकरण है, जैसा कि @ mhttk सुझाता है, या आप दावा कर रहे हैं कि अलग-अलग धागे उस चर में अलग-अलग स्थिति देखते हैं (जो बहुत अजीब लगता है), या कुछ और? – Rory

+0

@ रोरी - एक धागे में, _instance प्रारंभ हो जाता है। उसी धागे से बाद की कॉल में, यह अभी भी अपेक्षित के रूप में शुरू किया गया है। हालांकि जब कोई अन्य थ्रेड इसे एक्सेस करने का प्रयास करता है (कई मिनट बाद - यह एक समय मुद्दा नहीं है) यह शून्य है और उस थ्रेड द्वारा उपयोग के लिए पुनः आरंभ किया जाना चाहिए। – Eric

+0

यह बहुत अजीब है ना? मेरे अनुभव मेंनेट COM इंटरऑप (इंटरनेट एक्सप्लोरर के साथ जो समान है लेकिन स्पष्ट रूप से अलग है), ऐसा नहीं होता है। क्या यह COM अपार्टमेंट के साथ एक सामान्य बात है? क्या आप वाकई एक ही प्रक्रिया में हैं? – Rory

उत्तर

1

आपका स्थैतिक चर निश्चित रूप से ऐपडोमेन्स के बीच साझा नहीं किया गया है, इसलिए आप जो देख रहे हैं, वह अलग-अलग ऐपडोमेन दिए गए हैं।

मैं इसे इस तरह से काम करता है लगता है:

VSTO ऐड-इन रन का अपना AppDomain में। यदि आपके कैश ऑब्जेक्ट (या आरटीडी सर्वर) के लिए COM क्लास फ़ैक्टरी उस ऐपडोमेन के भीतर से बनाई गई है, तो इसे कॉलिंग ऐपडोमेन में लोड किया जाएगा। उस COM क्लास के बाद की पहुंच से यह पहले ही प्रक्रिया में लोड हो जाएगा, और मौजूदा इंस्टेंस का उपयोग करेगा।

हालांकि, अगर पहली सक्रियण स्वयं Excel द्वारा ट्रिगर की गई है, उदा। एक आरटीडी कॉल द्वारा, .NET लागू COM ऑब्जेक्ट को प्रक्रिया के डिफ़ॉल्ट AppDomain में लोड किया जाएगा। लोडिंग प्रक्रिया के इस हिस्से पर आपका कोई नियंत्रण नहीं है जब तक आप एक अप्रबंधित शिम नहीं बनाते, क्योंकि लोड होने पर 'आपका कोड' नहीं चल रहा है।

मेरे सिर के ऊपर से कुछ सुझाव:

  1. RTD के लिए कहता है आपके नेट ऐड-इन से संपर्क में हैं जो कुछ आवरण कार्यों बनाओ। इस तरह, आप यह सुनिश्चित कर सकते हैं कि आरटीडी क्लास एक्सेल के एप्लिकेशन को कॉल करने से पहले लोड हो। आरटीडी असली आरटीडी सेटअप करने के लिए।

  2. उपयोगकर्ता परिभाषित कार्यों के माध्यम से आरटीडी सर्वर से वास्तविक कैश तक पहुंच बनाएं - इस तरह एक्सेल ऐपडोमेन में कॉल करेगा जिसमें असली कैश है, भले ही यह वर्तमान ऐपडोमेन नहीं है जहां आरटीडी सर्वर रहता है।

  3. एप्लिकेशन के माध्यम से ऐड-इन ऑब्जेक्ट को पकड़ने का प्रयास करें। AddIns .... वास्तविक ऐड-इन COM ऑब्जेक्ट प्राप्त करने का एक तरीका है, और कैश पर जाने के लिए उस पर कुछ इंटरफ़ेस का उपयोग करें ..

  4. एक अप्रबंधित शिम बनाएं (अपने आरटीडी सर्वर के लिए "COM shim जादूगर" के लिए वेब पर खोजें)। किसी भी तरह से पता लगाएं कि कैसे अपना VSTO AppDomain लोड किया जाए, और फिर उस ऐपडोमेन में आरटीडी सर्वर लोड करें।

  5. देखें कि VSTO एड-इन को डिफ़ॉल्ट AppDomain में लोड करने का कोई तरीका है या नहीं। मुझे नहीं पता, लेकिन शायद एक झंडा या स्विच है जो "माइक्रोसॉफ्ट ऑफिस सिस्टम्स लोडर" (या जो भी हिस्सा अब कहा जाता है) को अलग ऐपडोमेन बनाने के लिए नहीं कहता है।

  6. सही उत्तर: Excel-Dna का उपयोग करें (अस्वीकरण: मैं डेवलपर हूं)। यह आपके प्रबंधित ऐड-इन में रिबन, आरटीडी और यूडीएफ का समर्थन करता है, बिना पंजीकरण की आवश्यकता होती है, और सब कुछ आपके ऐड-इन्स ऐपडोमेन में डाल दिया जाता है। यह मुफ़्त है, लेकिन आपकी सामग्री को बंद करने में कुछ समय और प्रयास लगेगा - आरटीडी मामूली है, लेकिन यदि आप रिबन और शीट एक्सेस (टेबल इत्यादि) के लिए बहुत सी VSTO सहायक वस्तुओं का उपयोग करते हैं, तो आपको इसके बारे में सोचना होगा यह थोड़ा सा

मुझे आशा है कि यह आपको कुछ विचार देता है।

--Govert--

-2

पहले, आप अपने उदाहरण घोषित करने के लिए चाहते हो सकता है के रूप में:

static DataCache _instance = new DataCache(); 

इस तरह से (नहीं यकीन है कि के लिए केवल एक), तुम्हें पता है _instance धागा सुरक्षित उत्पन्न होता है। धागे सुरक्षित सिंगलेट्स के विषय पर बहुत अधिक कवरेज है, लेकिन यह सबसे सरल समाधानों में से एक लगता है।

दूसरी बात यह हो सकता है आप को आजमाना चाह तरह

Lock (_lockObject) 
{ 
... 
} 

एक संरचना दोनों रीड और राईट के लिए है। इससे आपके धागे अलग-अलग धागे से सुरक्षित हो जाएंगे और लिखेंगे।

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

शुभकामनाएं!

+0

मुझे खेद है, यह मेरी समस्या का समाधान नहीं करता है। मैंने इस सवाल को स्पष्ट करने के लिए संपादित किया है कि एक मिनट थ्रेड के दौरान कई मिनट गुजरता है और अन्य थ्रेड इसका उपयोग करने का प्रयास करता है। यह थ्रेड सिंक्रनाइज़ेशन समस्या नहीं है, यह कुछ है कि .NET/COM कार्यान्वयन कैसे काम करता है। – Eric

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