मेरे पास एक लाइब्रेरी है जिसका उपयोग मैं डब्ल्यूसीएफ का उपयोग करता हूं ताकि सेटिंग्स प्राप्त करने के लिए http सेवा को कॉल किया जा सके। आम तौर पर पहली कॉल ~ 100 मिलीसेकंड लेती है और बाद में कॉल केवल कुछ मिलीसेकंड लेती है। लेकिन मुझे पता चला है कि जब मैं एक नया ऐपडोमेन बनाता हूं तो उस ऐपडोमेन से पहले डब्ल्यूसीएफ कॉल को 2.5 सेकंड से अधिक समय लगता है।नए ऐपडोमेन में किए गए पहले डब्ल्यूसीएफ कनेक्शन बहुत धीमे हैं
क्या किसी के पास कोई स्पष्टीकरण या ठीक है कि क्यों एक नए ऐपडोमेन में डब्ल्यूसीएफ चैनल की पहली रचना इतनी लंबी होगी?
ये बेंचमार्क परिणाम हैं (जब 64 बिट में रिलीज में संलग्न डिबगर के बिना चल रहा है), ध्यान दें कि किस नंबर के दूसरे सेट में पहली कनेक्शन लेता है 25 गुना से अधिक लंबे समय तक
Running in initial AppDomain
First Connection: 92.5018 ms
Second Connection: 2.6393 ms
Running in new AppDomain
First Connection: 2457.8653 ms
Second Connection: 4.2627 ms
यह एक पूर्ण उदाहरण नहीं है लेकिन पता चलता है कि मैं इन नंबरों का उत्पादन का सबसे:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Running in initial AppDomain");
new DomainRunner().Run();
Console.WriteLine();
Console.WriteLine("Running in new thread and AppDomain");
DomainRunner.RunInNewAppDomain("test");
Console.ReadLine();
}
}
class DomainRunner : MarshalByRefObject
{
public static void RunInNewAppDomain(string runnerName)
{
var newAppDomain = AppDomain.CreateDomain(runnerName);
var runnerProxy = (DomainRunner)newAppDomain.CreateInstanceAndUnwrap(typeof(DomainRunner).Assembly.FullName, typeof(DomainRunner).FullName);
runnerProxy.Run();
}
public void Run()
{
AppServSettings.InitSettingLevel(SettingLevel.Production);
var test = string.Empty;
var sw = Stopwatch.StartNew();
test += AppServSettings.ServiceBaseUrlBatch;
Console.WriteLine("First Connection: {0}", sw.Elapsed.TotalMilliseconds);
sw = Stopwatch.StartNew();
test += AppServSettings.ServiceBaseUrlBatch;
Console.WriteLine("Second Connection: {0}", sw.Elapsed.TotalMilliseconds);
}
}
AppServSettings.ServiceBaseUrlBatch करने के लिए कॉल के लिए एक सेवा के लिए एक चैनल बनाने और एक ही विधि बुला रहा है। मैंने कॉल देखने के लिए वायरशर्क का उपयोग किया है और सेवा से प्रतिक्रिया प्राप्त करने के लिए केवल एक मिलीसेकंड लेता है। यह निम्न कोड के साथ चैनल बनाता है:
public static ISettingsChannel GetClient()
{
EndpointAddress address = new EndpointAddress(SETTINGS_SERVICE_URL);
BasicHttpBinding binding = new BasicHttpBinding
{
MaxReceivedMessageSize = 1024,
OpenTimeout = TimeSpan.FromSeconds(2),
SendTimeout = TimeSpan.FromSeconds(5),
ReceiveTimeout = TimeSpan.FromSeconds(5),
ReaderQuotas = { MaxStringContentLength = 1024},
UseDefaultWebProxy = false,
};
cf = new ChannelFactory<ISettingsChannel>(binding, address);
return cf.CreateChannel();
}
एप्लिकेशन की रूपरेखा से यह पता चलता है कि पहले मामले में चैनल कारखाने के निर्माण और चैनल बनाकर और विधि बुला कम से कम 100 मिलीसेकेंड
में ले जाता है चैनल फैक्ट्री का निर्माण करने वाले नए ऐपडोमेन ने चैनल बनाने के लिए 763 मिलीसेकंड, 521 मिलीसेकंड, इंटरफेस पर विधि को कॉल करने के लिए 1,0 9 8 मिलीसेकंड लिया।
TestSettingsRepoInAppDomain.DomainRunner.Run() 2,660.00 TestSettingsRepoInAppDomain.AppServSettings.get_ServiceBaseUrlBatch() 2,543.47 Tps.Core.Settings.Retriever.GetSetting (स्ट्रिंग, !! 0, !! 0, !! 0) 2,542.66 टी पी एस। Core.Settings.Retriever.TryGetSetting (स्ट्रिंग, !! 0 &) 2,522.03 Tps.Core.Settings.ServiceModel.WcfHelper.GetClient() 1,371.21 Tps.Core.Settings.ServiceModel.IClientChannelExtensions.CallWithRetry (कक्षा System.ServiceModel.IClientChannel) 1,0 9 8.83
संपादित करें
.NET CLR लोडिंग ऑब्जेक्ट के साथ परफमन का उपयोग करने के बाद मैं देख सकता हूं कि जब यह दूसरा ऐपडोमेन लोड करता है तो यह प्रारंभ में प्रारंभिक रूप से स्मृति में अधिक कक्षाओं को लोड कर रहा है। पहली फ्लैट लाइन एक विराम है जिसे मैंने पहले एपडोमेन के बाद रखा था, वहां 218 वर्ग लोड हुए हैं। दूसरा ऐपडोमेन 1,944 कुल वर्गों को लोड करने का कारण बनता है।
मुझे लगता है कि यह सभी कक्षाओं को लोड करने का मानना है, इसलिए अब सवाल यह है कि यह कौन सी कक्षाएं लोड हो रही है और क्यों?
अद्यतन
जवाब पता चला है क्योंकि तथ्य यह है कि केवल एक AppDomain देशी छवि प्रणाली DLLs का लाभ लेने के लिए सक्षम है की हो। तो दूसरे एपडोमेन में धीमी गति से इसे सभी सिस्टम को फिर से भरना पड़ा। * डब्ल्यूसीएफ द्वारा उपयोग किए जाने वाले डीएलएस। पहला एपडोमेन उन डीएलएस के पूर्व ngened देशी संस्करणों का उपयोग कर सकता है, इसलिए यह एक ही स्टार्टअप लागत नहीं थी।
LoaderOptimizationAttribute की जांच कर रही है कि Petar सुझाव दिया, कि वास्तव में इस मुद्दे को ठीक करने के लिए, पहली बार
यहाँ WCF से अधिक सामान का उपयोग करने के रूप में उतना ही समय लेने के लिए या तो MultiDomain or MultiDomainHost परिणाम दूसरा AppDomain में का उपयोग कर लग रहा था के बाद आप डिफ़ॉल्ट विकल्प देख सकते हैं, ध्यान दें कि विधानसभाओं के दूसरे AppDomain कोई भी में मूल निवासी कहते हैं, जिसका अर्थ है कि वे सभी rejitted जा करने के लिए है जो समय
यहाँ जोड़ने के बाद है के सभी ले रहा था था, LoaderOptimiza मुख्य रूप से टियन (लोडर ऑप्टिमाइजेशन। मल्टीडीडोमेन)। आप देख सकते हैं कि सब कुछ साझा AppDomain
यहां उपयोगकर्ता LoaderOptimization (LoaderOptimization.MultiDomainHost) मुख्य करने के बाद है में भरी हुई है। आप देख सकते हैं कि सभी प्रणाली DLLs साझा कर रहे हैं, लेकिन अपने ही DLLs और GAC में कोई नहीं प्रत्येक AppDomain
सेवा का उपयोग कर MultiDomainHost जवाब है इस सवाल के लिए कहा जाए के लिएतो में अलग से लोड किए गए हैं, क्योंकि इसमें तेजी से स्टार्टअप समय है और मैं गतिशील रूप से निर्मित असेंबली को हटाने के लिए ऐपडोमेन को अनलोड कर सकता हूं कि सेवा
के लिए उस कोर के लिए अधिकतम किया गया था, धन्यवाद, जो वास्तव में नए ऐपडोमेन में पहली बार और 2 एमएमएस के लिए 35 एमएस होने का समय कम करता है दूसरा, लेकिन क्या यह दूसरी ऐपडोमेन में लोड की गई असेंबली को उतारने से रोक देगा? ऐप ऐपडोमेन का उपयोग करने का एक कारण यह है कि यह एक लंबी चल रही सेवा है जिसे एक क्रिया करने के लिए कस्टम कोड लोड करने की आवश्यकता होती है, इसलिए मुझे अभी भी कुछ असेंबली को उतारने में सक्षम होना चाहिए ताकि सेवा का आकार असंबद्ध न हो । – BrandonAGr
यह सेटिंग दूसरे ऐपडोमेन से असेंबली असेंबली को रोक नहीं सकती है। –
कौन सा ऐप स्क्रीन शॉट्स का उत्पादन कर रहा है? Sysinternals सामान? –