2011-04-25 24 views
11

मैंने असेंबली की गतिशील लोडिंग और उन विधानसभाओं से कक्षा के उदाहरण बनाने के लिए कोड का एक छोटा सा टुकड़ा लिखा है, जिसमें निष्पादन योग्य, गतिशील रूप से लोड होने के लिए एक परीक्षण lib और एक नई लाइब्रेरी में गतिशील असेंबली लोड करने के लिए लोडर लाइब्रेरी Appdomain। लोडर लाइब्रेरी को निष्पादन योग्य और गतिशील लाइब्रेरी दोनों द्वारा संदर्भित किया जाता है।लोडरऑप्टिमाइजेशन का प्रभाव

//executable 
[System.STAThreadAttribute()] 
[System.LoaderOptimization(LoaderOptimization.MultiDomain)] 
static void Main(string[] args) 
{  
    AppDomainSetup domainSetup = new AppDomainSetup() 
    { 
     ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase, 
     ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile, 
     ApplicationName = AppDomain.CurrentDomain.SetupInformation.ApplicationName, 
     LoaderOptimization = LoaderOptimization.MultiDomain 
    }; 
    AppDomain childDomain = AppDomain.CreateDomain("MyDomain", null, domainSetup); 
    Console.WriteLine(AppDomain.CurrentDomain.SetupInformation.LoaderOptimization.ToString()); 
    Console.WriteLine(childDomain.SetupInformation.LoaderOptimization.ToString()); 

    byte[] assembly = null; 
    string assemblyName = "CSTestLib"; 

    using (FileStream fs = new FileStream(assemblyName+".dll",FileMode.Open)) 
    { 
     byte[] byt = new byte[fs.Length]; 
     fs.Read(byt,0,(int)fs.Length); 
     assembly = byt;   
    } 

    object[] pararmeters = {assemblyName,assembly}; 
    string LoaderAssemblyName = typeof(AssemblyLoader).Assembly.FullName; 
    string LoaderClassName = typeof(AssemblyLoader).FullName; 
    AssemblyLoader assloader = (AssemblyLoader)childDomain.CreateInstanceAndUnwrap(LoaderAssemblyName,LoaderClassName , true, BindingFlags.CreateInstance, null, parameters, null, null); 


    object obj = assloader.Load("CSTestLib.Class1"); 
    object obj2 = assloader.Load("CSTestLib.Class2"); 

    AppDomain.Unload(childDomain); 

    Console.ReadKey(); 
} 

//Dynamic Lib 
using System; 


namespace CSTestLib 
{ 
    public class Class1 :MarshalByRefObject 
    { 
     public Class1() { } 
    } 



    public class Class2 : MarshalByRefObject 
    { 
     public Class2() { } 
    } 
} 

//Loader Library 


using System; 

namespace LoaderLibrary 
{ 
    public class AssemblyLoader : MarshalByRefObject 
    { 
     string assemblyName; 
     public AssemblyLoader(string assName, byte[] ass) 
     { 
      assemblyName = assName; 
      AppDomain.CurrentDomain.Load(ass); 
      Console.WriteLine(AppDomain.CurrentDomain.FriendlyName + " " + AppDomain.CurrentDomain.SetupInformation.LoaderOptimization.ToString()); 
     } 

     public object Load(string className) 
     { 
      object ret = null; 
      try 
      { 
       ret = AppDomain.CurrentDomain.CreateInstanceAndUnwrap(assemblyName, className); 
      } 
      catch (System.Exception ex) 
      { 
       Console.WriteLine(ex.Message); 
      } 
      return ret; 
     } 
    } 
} 
  1. यहाँ मैं LoaderOptimizationAttributemain() विधि पर सेट लेकिन AppDomain.CurrentDomain.SetupInformation.LoaderOptimization.ToString(); कहना है कि वह NotSpecified क्यों है?

  2. MultiDomain और MultiDomainHost के बीच अंतर मुझे इतना स्पष्ट नहीं है। केवल जीएसी असेंबली के लिए MultiDomainHost है? मेरी स्थिति के लिए जो अधिक उपयुक्त है?

  3. this

    JIT संकलित कोड के अनुसार, विधानसभाओं लोड से संदर्भ में लोड के लिए साझा नहीं किया जा सकता की LoadFrom विधि विधानसभा वर्ग का उपयोग कर, या भार के का उपयोग कर छवियों से भरी हुई लोड विधि जो बाइट सरणी निर्दिष्ट करती है।

तो मैं अगर एक विधानसभा डोमेन तटस्थ या नहीं भरी हुई है कैसे पता लगा सकते हैं? मैं कैसे आश्वस्त कर सकता हूं कि यह डोमेन-तटस्थ लोड है?

उत्तर

11

यह विशेषता केवल तभी प्रभाव डालती है जब आप अपने आवेदन की गर्म शुरुआत को तेज करने के लिए 0 असेंबली NGen के साथ अपनी असेंबली प्रीकंपाइल करते हैं। जब आप MultiDomain या MultiDomainHost निर्दिष्ट करते हैं तो आप precompiled (ngenned) असेंबली का उपयोग सक्षम करते हैं। आप प्रक्रिया एक्सप्लोरर के साथ इसे सत्यापित कर सकते हैं जहां आप लोड मॉड्यूल की सूची देख सकते हैं।

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

अपने उदाहरण में आप असेंबली को एक बाइट सरणी में लोड करते हैं जो प्रबंधित ढेर में स्थित है और आपकी निजी बाइट गिनती बढ़ाता है। यह प्रक्रियाओं के बीच डेटा साझा करना असंभव बनाता है। केवल उन पृष्ठों को पढ़ें जिन्हें आपकी हार्ड डिस्क पर समकक्ष है प्रक्रियाओं के बीच साझा किया जा सकता है। यही कारण है कि विशेषता का कोई प्रभाव नहीं पड़ता है। यदि आप गर्म स्टार्टअप प्रदर्शन के कारक 2 के बाद हैं तो यह वह विशेषता है जिसे आप ढूंढ रहे थे। किसी और चीज के लिए यह प्रासंगिक नहीं है।

अब वापस अपने मूल प्रश्न के:

  1. यह सेट किया गया है, लेकिन जब आप एक डिबगर के तहत अपने आवेदन शुरू इस MultiDomain विशेषता नजरअंदाज कर दिया है। जब आप इसे डीबगर के बाहर शुरू करते हैं तो आपको अपेक्षित परिणाम मिलेंगे।
  2. हां MultiDomainHostAppDomain केवल हस्ताक्षरित असेंबली के लिए तटस्थता को सक्षम करता है अन्य सभी साझा नहीं किए जाते हैं।
  3. कोड साझाकरण केवल तभी हो सकता है जब यह प्रीकंपिल्ड हो। असली सवाल यह है कि कैसे जांच करें कि असेंबली प्रीकंपिल्ड है या नहीं? मैं लोड किए गए मॉड्यूल की सूची देखकर प्रक्रिया एक्सप्लोरर के साथ करता हूं। जब मेरी लोडेड असेंबली मूल छवि कैश और एक .ni एक्सटेंशन के पथ के साथ दिखाई देती है तो मुझे यकीन है कि प्रीकंपील्ड छवि का उपयोग किया जा रहा है। आप इसे fuslogvw के साथ भी देख सकते हैं जब आप देशी छवियों पर रेडियो बटन सेट करते हैं ताकि यह जांच सके कि देशी छवियों को रनटाइम द्वारा क्यों उपयोग नहीं किया गया था।
+0

ऐसा लगता है कि विशेषता वास्तव में प्रभाव डालती है। डीबगर संलग्न रिटर्न के साथ चल रहा है 'निर्दिष्ट नहीं किया गया' ... डीबगर रिटर्न के बिना चल रहा है 'मल्टीडोमेन' ... शायद कोई इसकी पुष्टि कर सकता है। – Matthias

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

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