سؤال

أقوم ببعض التجارب مع Microsoft Dynamics CRM.أنت تتفاعل معه من خلال خدمات الويب وقمت بإضافة مرجع ويب إلى مشروعي.واجهة خدمة الويب غنية جدًا، ويبلغ حجم "Reference.cs" الذي تم إنشاؤه حوالي 90 ألف موقع.

أنا أستخدم مرجع الويب في تطبيق وحدة التحكم.غالبًا ما أقوم بتغيير شيء ما وإعادة ترجمته وتشغيله.التجميع سريع، ولكن تحديث مرجع خدمة الويب بطيء جدًا، ويستغرق حوالي 15 إلى 20 ثانية: CrmService service = new CrmService(); يكشف التوصيف أن كل الوقت يتم إنفاقه في مُنشئ SoapHttpClientProtocol.

من الواضح أن السبب وراء ذلك هو حقيقة أن كود تسلسل XML (غير المضمن في 90k loc المذكور أعلاه) يتم إنشاؤه في وقت التشغيل، قبل أن يتم JIT'ed.يحدث هذا أثناء استدعاء المنشئ.الانتظار محبط إلى حد ما عند اللعب وتجربة الأشياء.

لقد قمت بتجربة مجموعات مختلفة من sgen.exe وngen وXGenPlus (والتي تستغرق عدة ساعات وتولد 500 ميجابايت من التعليمات البرمجية الإضافية) ولكن دون جدوى.لقد فكرت في تنفيذ خدمة Windows التي تحتوي على عدد قليل من مثيلات CrmService الجاهزة للاستخدام عند الحاجة ولكن هذا يبدو مبالغًا فيه.

أيه أفكار؟

هل كانت مفيدة؟

المحلول

ما يلي ممزق من هذا موضوع في منتديات VMWare:

مرحبا يا رفاق،

لقد وجدنا أن sgen.exe يعمل.إنه مجرد أن هناك بضع خطوات إضافية تتجاوز الإنشاء المسبق لملفات dll التسلسلية التي فاتناها في هذا الموضوع.هنا هي التعليمات التفصيلية

مشكلة

عند استخدام VIM 2.0 SDK من .NET، يتطلب الأمر وقتًا طويلاً لإنشاء فئة VimService.(فئة VimService هي فئة الوكيل التي تم إنشاؤها عن طريق تشغيل 'wsdl.exe vim.wsdl vimService.wsdl')

بمعنى آخر، السطر التالي من التعليمات البرمجية:

_service = new VimService();

قد يستغرق تنفيذه حوالي 50 ثانية.

سبب

على ما يبدو، .NET XmlSerializer يستخدم System.Xml.Serialization.* السمات التي توضح فئات الوكيل لإنشاء كود التسلسل في وقت التشغيل.عندما تكون فئات الوكيل كثيرة وكبيرة، كما هو الحال مع التعليمات البرمجية الموجودة في VimService.cs، فقد يستغرق إنشاء رمز التسلسل وقتًا طويلاً.

حل

هذه مشكلة معروفة تتعلق بكيفية عمل برنامج تسلسل Microsoft .NET.

فيما يلي بعض المراجع التي توفرها MSDN حول حل هذه المشكلة:

http://msdn2.microsoft.com/en-us/library/bk3w6240.aspx http://msdn2.microsoft.com/en-us/library/system.xml.serialization.xmlserializerassemblyattribute.aspx

لسوء الحظ، لا يصف أي من المراجع المذكورة أعلاه الحل الكامل للمشكلة.وبدلاً من ذلك يركزون على كيفية الإنشاء المسبق لرمز تسلسل XML.

يتضمن الإصلاح الكامل الخطوات التالية:

  1. قم بإنشاء تجميع (DLL) باستخدام رمز تسلسل XML الذي تم إنشاؤه مسبقًا

  2. قم بإزالة كافة الإشارات إلى سمات System.Xml.Serialization.* من رمز الوكيل (أي.من ملف VimService.cs)

  3. قم بتعليق فئة الوكيل الرئيسية باستخدام XmlSerializerAssemblyAttribute لتوجيهها إلى مكان تجميع مُسلسل XML.

يؤدي تخطي الخطوة 2 إلى تحسن بنسبة 20% فقط في وقت إنشاء مثيل الملف VimService فصل.يؤدي تخطي الخطوة 1 أو 3 إلى رمز غير صحيح.مع الخطوات الثلاث يتم تحقيق تحسن بنسبة 98٪.

فيما يلي تعليمات خطوة بخطوة:

قبل البدء، تأكد من أنك تستخدم أدوات .NET verison 2.0.لن يعمل هذا الحل مع الإصدار 1.1 من .NET لأن أداة sgen وأداة XmlSerializationAssemblyAttribute متوفرة فقط في الإصدار 2.0 من .NET

  1. قم بإنشاء ملف VimService.cs من WSDL، باستخدام wsdl.exe:

    wsdl.exe vim.wsdl vimService.wsdl

    سيؤدي هذا إلى إخراج ملف VimService.cs في الدليل الحالي

  2. قم بتجميع VimService.cs في مكتبة

    csc /t:library /out:VimService.dll VimService.cs

  3. استخدم أداة sgen لإنشاء وتجميع مُسلسلات XML مسبقًا:

    sgen /p VimService.dll

    سيؤدي هذا إلى إخراج VimService.XmlSerializers.dll في الدليل الحالي

  4. ارجع إلى ملف VimService.cs وقم بإزالة الكل System.Xml.Serialization.* صفات.نظرًا لأن رمز الكود كبير، فإن أفضل طريقة لتحقيق ذلك هي استخدام بعض أدوات استبدال التعبير العادي.كن حذرًا أثناء قيامك بذلك لأنه لا تظهر كافة السمات على السطر بمفردها.بعضها مضمن كجزء من إعلان الطريقة.

    إذا وجدت هذه الخطوة صعبة، فإليك طريقة مبسطة للقيام بذلك:

    بافتراض أنك تكتب C#، قم بإجراء استبدال عام على السلسلة التالية:

    [System.Xml.Serialization.XmlIncludeAttribute

    واستبدلها بـ:

    // [System.Xml.Serialization.XmlIncludeAttribute

    هذا سوف يتخلص من Xml.Serialization السمات التي تعتبر أكبر المسببين للتباطؤ من خلال التعليق عليها.إذا كنت تستخدم لغة .NET أخرى، فما عليك سوى تعديل السلسلة المستبدلة ليتم التعليق عليها ببادئة وفقًا لبناء جملة تلك اللغة.سيوفر لك هذا النهج المبسط أقصى قدر من التسريع الذي يمكنك الحصول عليه.تؤدي إزالة بقية سمات Xml.Serialization إلى زيادة السرعة بمقدار 0.2 ثانية فقط.

  5. أضف السمة التالية إلى فئة VimService في VimService.cs:

    [System.Xml.Serialization.XmlSerializerAssemblyAttribute(AssemblyName = "VimService.XmlSerializers")]

    يجب أن تنتهى مع بعض الأشياء التى تحبها:

    // ... Some code here ... [System.Xml.Serialization.XmlSerializerAssemblyAttribute(AssemblyName = "VimService.XmlSerializers")] public partial class VimService : System.Web.Services.Protocols.SoapHttpClientProtocol { // ... More code here

  6. قم بإعادة إنشاء مكتبة VimSerice.dll بواسطة

    csc /t:library /out:VimService.dll VimService.cs

  7. الآن، من التطبيق الخاص بك، يمكنك إضافة مرجع إلى مكتبة VimSerice.dll.

  8. قم بتشغيل التطبيق الخاص بك وتحقق من تقليل وقت إنشاء كائن VimService.

ملاحظات إضافية

تعد أداة sgen بمثابة صندوق أسود ويختلف سلوكها اعتمادًا على ما لديك في ملف Machine.config الخاص بك.على سبيل المثال، من المفترض افتراضيًا إخراج تعليمات برمجية محسّنة غير قابلة للتصحيح، ولكن هذا ليس هو الحال دائمًا.للحصول على بعض الرؤية داخل الأداة، استخدم علامة /k في الخطوة 3، مما سيؤدي إلى احتفاظها بجميع ملفاتها المؤقتة التي تم إنشاؤها، بما في ذلك الملفات المصدر وملفات خيارات سطر الأوامر التي أنشأتها.

حتى بعد الإصلاح أعلاه، فإن الوقت المستغرق لإنشاء مثيل لفئة VimService لأول مرة ليس فوريًا (1.5 ثانية).وبناء على الملاحظة التجريبية، يبدو أن غالبية الوقت المتبقي يرجع إلى معالجة الملف SoapDocumentMethodAttribute صفات.وفي هذه المرحلة، ليس من الواضح كيف يمكن تقليل هذا الوقت.لا يأخذ تجميع XmlSerializer الذي تم إنشاؤه مسبقًا في الاعتبار السمات المتعلقة بـ SOAP، لذا يجب أن تظل هذه السمات في التعليمات البرمجية.والخبر السار هو أن الإنشاء الأول لفئة VimService لهذا التطبيق فقط يستغرق وقتًا طويلاً.لذا، إذا كانت الـ 1.5 ثانية الإضافية تمثل مشكلة، فيمكن للمرء أن يحاول إجراء إنشاء مثيل وهمي لهذه الفئة في بداية التطبيق كوسيلة لتحسين تجربة المستخدم في وقت تسجيل الدخول.

نصائح أخرى

قد ترغب في النظر في Sgen.exe الأداة التي تأتي مع .NET.يوجد أيضًا شيء صغير مفيد في صفحة "Build" لخصائص مشروع C# في Visual Studio، في الجزء السفلي، يسمى "Build serialization Assembly" الذي يتم تشغيله تلقائيًا Sgen لك.

وأعتقد أن هذه ليست قضية SGEN. لقد بحثت في قانون البناء، وأرى أنها تفعل الكثير من التفكير (استنادا إلى XmlIncludeAttribute على الطبقة). وهو يعكس على كل منهم، ويمكن أن يستغرق وقتا طويلا حقا.

وهناك تجميع ولدت قبل XmlSerializer التي تأتي مع CRM. تحقق لمعرفة ما إذا كان لديك SdkTypeProxy.XmlSerializers.dll وSdkProxy.XmlSerializers.dll في GAC.

إذا كنت لا ثم وهذا يعني أنه عندما تقوم بإنشاء CrmService، صافي سيولد تجميع XmlSerializer الذي يمكن أن يستغرق بعض الوقت. ويساعد هذا الأمل

وجئت عبر هذا الموضوع عند محاولة معرفة لماذا دعواتي SoapHttpClientProtocol الأولية قد أخذ وقتا طويلا.

ولقد وجدت أن وضع وكيل فارغة / فارغ توقف الكشف التلقائي وكيل من الحدوث - وهذا كان يأخذ تصل إلى 7 ثوان على المكالمة الأولي:

this.Proxy = GlobalProxySelection.GetEmptyWebProxy();

ولقد استخدمت فوق إجابة مفصلة كدليل، وذهب بضع خطوات إلى الأمام، مما يجعل برنامج نصي لأتمتة عملية. يتم النصي من ملفين:

وgenerateproxy.bat:

REM if your path for wsdl, csc or sgen is missing, please add it here (it varies from machine to machine)
set PATH=%PATH%;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools;C:\Program Files (x86)\MSBuild\14.0\Bin

wsdl http://localhost:57237/VIM_WS.asmx?wsdl REM create source code out of WSDL
PowerShell.exe -ExecutionPolicy Bypass -Command "& '%~dpn0.ps1'" REM proces source code (remove annotations, add other annotation, put class into namespace)
csc /t:library /out:references\VIM_Service.dll VIM_WS.cs REM compile source into dll
sgen /p references\VIM_Service.dll /force REM generate serializtion dll

وgenerateproxy.ps1

(Get-Content VIM.cs) | 
    ForEach-Object { 
        $_ -replace "(?<attr>\[global::System.Xml.Serialization.[^\]]*\])", "/*${attr}*/" `
            -replace "public partial class VIM", "[System.Xml.Serialization.XmlSerializerAssemblyAttribute(AssemblyName = ""VIM_Service.XmlSerializers"")] `npublic partial class VIM" `
            -replace "using System;", "namespace Classes.WS_VIM {   `n`nusing System;"
    } |
Set-Content VIM.cs
Add-Content VIM.cs "`n}"

ولقد أضفت هذه الملفين إلى المشروع العميل، وفي حالة ما قبل بناء اضفت خطوط

cd..\..
generateproxy

ولذا، وقبل كل بناء، يتم إعادة الطبقات بروكسي، والمطور (تقريبا) لا حاجة للتفكير في الامر. وفي الوقت نفسه بناء، يجب أن يكون WS وتشغيلها، ويجب أن يكون URL في ملف الخفافيش. ونتيجة لprebuild، واثنين من مبارد تجديد في فرعي المشروع العميل <م> المراجع . بعد تنفيذ أول من النصوص، يجب عليك إضافة إشارة إلى دلل الجديد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top