ما الذي يجعل بدء تشغيل تطبيق WPF بطيئًا؟

StackOverflow https://stackoverflow.com/questions/868841

  •  22-08-2019
  •  | 
  •  

سؤال

لقد لاحظت أن بدء تشغيل تطبيق WPF يكون بطيئًا جدًا في بعض الأحيان.هل يعرف أحد ما إذا كان السبب هو تهيئة العناصر أو تحميل ملفات DLL أو أي شيء آخر؟

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

المحلول

تم استخراج النص أدناه من مقالة MSDN هذه حول تحسين وقت بدء تشغيل تطبيقات WPF (يحرر:اندمجت الآن في وقت بدء تشغيل تطبيق WPF)

وقت بدء تشغيل التطبيق

يمكن أن يختلف مقدار الوقت المطلوب لبدء تطبيق WPF بشكل كبير.يصف هذا الموضوع تقنيات متنوعة لتقليل وقت بدء التشغيل الفعلي والمتصور لتطبيق Windows Presentation Foundation (WPF).

فهم بدء التشغيل البارد وبدء التشغيل الدافئ

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

يحدث بدء التشغيل الدافئ عندما تكون معظم الصفحات الخاصة بمكونات وقت تشغيل اللغة العامة الرئيسية (CLR) محملة بالفعل في الذاكرة، مما يوفر وقت الوصول إلى القرص باهظ الثمن.ولهذا السبب يبدأ التطبيق المُدار بشكل أسرع عند تشغيله مرة ثانية.

تنفيذ شاشة البداية

في الحالات التي يوجد فيها تأخير كبير لا مفر منه بين بدء تشغيل التطبيق وعرض واجهة المستخدم الأولى، قم بتحسين وقت بدء التشغيل المدرك باستخدام شاشة البداية.يعرض هذا الأسلوب صورة على الفور تقريبًا بعد أن يبدأ المستخدم التطبيق.عندما يكون التطبيق جاهزًا لعرض واجهة المستخدم الأولى الخاصة به، تتلاشى شاشة البداية.بدءًا من .NET Framework 3.5 SP1، يمكنك استخدام شاشة البداية فئة لتنفيذ شاشة البداية.لمزيد من المعلومات، راجع كيف:إضافة شاشة البداية إلى تطبيق WPF.

يمكنك أيضًا تنفيذ شاشة البداية الخاصة بك باستخدام رسومات Win32 الأصلية.عرض التنفيذ الخاص بك قبل يجري تسمى الطريقة .

تحليل رمز بدء التشغيل

تحديد سبب بدء التشغيل البارد البطيء.قد يكون إدخال/إخراج القرص هو المسؤول، ولكن هذا ليس هو الحال دائمًا.بشكل عام، يجب عليك تقليل استخدام الموارد الخارجية، مثل الشبكة أو خدمات الويب أو القرص.

قبل الاختبار، تأكد من عدم استخدام أي تطبيقات أو خدمات أخرى قيد التشغيل لتعليمات برمجية مُدارة أو تعليمات برمجية WPF.

ابدأ تشغيل تطبيق WPF فورًا بعد إعادة التشغيل، وحدد المدة التي يستغرقها العرض.إذا كانت جميع عمليات التشغيل اللاحقة لتطبيقك (بدء التشغيل الدافئ) أسرع بكثير، فمن المرجح أن يكون سبب مشكلة بدء التشغيل البارد هو الإدخال/الإخراج.

إذا لم تكن مشكلة بدء التشغيل البارد لتطبيقك مرتبطة بالإدخال/الإخراج، فمن المحتمل أن يقوم تطبيقك ببعض التهيئة أو العمليات الحسابية المطولة، أو ينتظر حتى يكتمل بعض الأحداث، أو يتطلب الكثير من تجميع JIT عند بدء التشغيل.تصف المقاطع التالية بعض هذه المواقف بمزيد من التفصيل.

تحسين تحميل الوحدة النمطية

استخدم أدوات مثل Process Explorer (Procexp.exe) وTlist.exe لتحديد الوحدات النمطية التي يقوم تطبيقك بتحميلها.يعرض الأمر Tlist <pid> كافة الوحدات التي تم تحميلها بواسطة العملية.

على سبيل المثال، إذا لم تكن متصلاً بالويب ورأيت أنه تم تحميل System.Web.dll، فهذا يعني أن هناك وحدة نمطية في التطبيق الخاص بك تشير إلى هذا التجميع.تحقق للتأكد من أن المرجع ضروري.

إذا كان تطبيقك يحتوي على وحدات متعددة، فقم بدمجها في وحدة واحدة.يتطلب هذا الأسلوب حملًا أقل لتحميل تجميع CLR.يعني عدد أقل من التجميعات أيضًا أن CLR يحافظ على حالة أقل.

تأجيل عمليات التهيئة

فكر في تأجيل رمز التهيئة حتى بعد عرض نافذة التطبيق الرئيسية.

انتبه إلى أنه قد يتم إجراء التهيئة داخل مُنشئ فئة، وإذا كان رمز التهيئة يشير إلى فئات أخرى، فقد يتسبب ذلك في حدوث تأثير متتالي يتم فيه تنفيذ العديد من مُنشئي الفئة.

تجنب تكوين التطبيق

خذ بعين الاعتبار تجنب تكوين التطبيق.على سبيل المثال، إذا كان التطبيق يحتوي على متطلبات تكوين بسيطة ولديه أهداف صارمة لوقت بدء التشغيل، فقد تكون إدخالات التسجيل أو ملف INI البسيط بديلاً أسرع لبدء التشغيل.

استخدم GAC

إذا لم يتم تثبيت التجميع في ذاكرة التخزين المؤقت للتجميع العمومي (GAC)، فستكون هناك تأخيرات ناجمة عن التحقق من التجزئة للتجميعات ذات الأسماء الواضحة وعن طريق التحقق من صحة صورة Ngen إذا كانت الصورة الأصلية لهذا التجميع متوفرة على الكمبيوتر.يتم تخطي التحقق من الاسم الواضح لكافة التجميعات المثبتة في GAC.لمزيد من المعلومات، راجع Gacutil.exe (أداة التخزين المؤقت للتجميع العمومي).

استخدم Ngen.exe

فكر في استخدام Native Image Generator (Ngen.exe) في تطبيقك.استخدام Ngen.exe يعني تداول استهلاك وحدة المعالجة المركزية لمزيد من الوصول إلى القرص لأن الصورة الأصلية التي تم إنشاؤها بواسطة Ngen.exe من المرجح أن تكون أكبر من صورة MSIL.

لتحسين وقت بدء التشغيل الدافئ، يجب عليك دائمًا استخدام Ngen.exe في التطبيق الخاص بك، لأن هذا يتجنب تكلفة وحدة المعالجة المركزية لتجميع JIT لرمز التطبيق.

في بعض سيناريوهات بدء التشغيل البارد، قد يكون استخدام Ngen.exe مفيدًا أيضًا.وذلك لأنه ليس من الضروري تحميل برنامج التحويل البرمجي JIT (mscorjit.dll).

يمكن أن يؤدي وجود وحدتي Ngen وJIT إلى أسوأ النتائج.وذلك لأنه يجب تحميل mscorjit.dll، وعندما يعمل مترجم JIT على التعليمات البرمجية الخاصة بك، يجب الوصول إلى العديد من الصفحات في صور Ngen عندما يقرأ مترجم JIT البيانات التعريفية للتجميعات.

نجين وانقر مرة واحدة

يمكن للطريقة التي تخطط بها لنشر تطبيقك أيضًا أن تُحدث فرقًا في وقت التحميل.لا يدعم نشر تطبيق ClickOnce Ngen.إذا قررت استخدام Ngen.exe لتطبيقك، فسيتعين عليك استخدام آلية نشر أخرى، مثل Windows Installer.

لمزيد من المعلومات، راجع Ngen.exe (مولد الصور الأصلي).

إعادة التأسيس وتضارب عناوين DLL

إذا كنت تستخدم Ngen.exe، فكن على علم بأن إعادة التأسيس يمكن أن تحدث عند تحميل الصور الأصلية في الذاكرة.إذا لم يتم تحميل ملف DLL على عنوانه الأساسي المفضل لأن نطاق العنوان هذا مخصص بالفعل، فسيقوم برنامج تحميل Windows بتحميله على عنوان آخر، وهو ما قد يستغرق وقتًا طويلاً.

يمكنك استخدام أداة Virtual Address Dump (Vadump.exe) للتحقق مما إذا كانت هناك وحدات نمطية تكون كافة الصفحات فيها خاصة.إذا كانت هذه هي الحالة، فقد يكون تم إعادة تأسيس الوحدة النمطية إلى عنوان مختلف.ولذلك، لا يمكن مشاركة صفحاته.

لمزيد من المعلومات حول كيفية تعيين العنوان الأساسي، راجع Ngen.exe (مولد الصور الأصلي).

تحسين رمز المصادقة

يضيف التحقق من رمز المصادقة إلى وقت بدء التشغيل.يجب التحقق من التجميعات الموقعة برمز المصادقة من خلال المرجع المصدق (CA).يمكن أن يستغرق هذا التحقق وقتًا طويلاً، لأنه قد يتطلب الاتصال بالشبكة عدة مرات لتنزيل قوائم إبطال الشهادات الحالية.كما أنه يتأكد من وجود سلسلة كاملة من الشهادات الصالحة على المسار إلى جذر موثوق به.يمكن أن يترجم هذا إلى عدة ثوان من التأخير أثناء تحميل التجميع.

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

بدءًا من .NET Framework 3.5، يوجد خيار تكوين يسمح بتجاوز التحقق من رمز المصادقة.للقيام بذلك، قم بإضافة الإعداد التالي إلى ملف app.exe.config:

<configuration>
 <runtime>
    <generatePublisherEvidence enabled="false"/>
  </runtime>
</configuration>

مقارنة الأداء على نظام التشغيل Windows Vista

يمتلك مدير الذاكرة في نظام التشغيل Windows Vista تقنية تسمى SuperFetch.يقوم SuperFetch بتحليل أنماط استخدام الذاكرة بمرور الوقت لتحديد محتوى الذاكرة الأمثل لمستخدم معين.ويعمل بشكل مستمر للحفاظ على هذا المحتوى في جميع الأوقات.

يختلف هذا الأسلوب عن تقنية الجلب المسبق المستخدمة في نظام التشغيل Windows XP، والتي تقوم بتحميل البيانات مسبقًا إلى الذاكرة دون تحليل أنماط الاستخدام.بمرور الوقت، إذا كان المستخدم يستخدم تطبيق WPF الخاص بك بشكل متكرر على نظام التشغيل Windows Vista، فقد يتحسن وقت بدء التشغيل البارد لتطبيقك.

استخدم AppDomains بكفاءة

إذا كان ذلك ممكنًا، قم بتحميل التجميعات في منطقة التعليمات البرمجية المحايدة للمجال للتأكد من استخدام الصورة الأصلية، في حالة وجودها، في كافة AppDomains التي تم إنشاؤها في التطبيق.

للحصول على أفضل أداء، قم بفرض اتصال فعال عبر النطاقات عن طريق تقليل المكالمات عبر النطاقات.عندما يكون ذلك ممكنًا، استخدم الاستدعاءات بدون وسيطات أو باستخدام وسيطات من النوع البدائي.

استخدم سمة NeutralResourcesLanguage

استخدم ال NeutralResourcesLanguageAttribute لتحديد الثقافة المحايدة ل مدير موارد.يتجنب هذا الأسلوب عمليات البحث عن التجميع غير الناجحة.

استخدم فئة BinaryFormatter للتسلسل

إذا كان يجب عليك استخدام التسلسل، استخدم BinaryFormatter الصف بدلا من XmlSerializer فصل.ال BinaryFormatter يتم تطبيق الفئة في مكتبة الفئات الأساسية (BCL) في تجميع mscorlib.dll.ال XmlSerializer يتم تنفيذه في تجميع System.Xml.dll، والذي قد يكون ملف DLL إضافيًا ليتم تحميله.

إذا كان يجب عليك استخدام XmlSerializer فئة، يمكنك تحقيق أداء أفضل إذا قمت بإنشاء مجموعة التسلسل مسبقًا.

قم بتكوين ClickOnce للتحقق من التحديثات بعد بدء التشغيل

إذا كان تطبيقك يستخدم ClickOnce، فتجنب الوصول إلى الشبكة عند بدء التشغيل عن طريق تكوين ClickOnce للتحقق من موقع النشر بحثًا عن التحديثات بعد بدء تشغيل التطبيق.

إذا كنت تستخدم نموذج تطبيق متصفح XAML (XBAP)، فضع في اعتبارك أن ClickOnce يتحقق من موقع النشر بحثًا عن التحديثات حتى إذا كان XBAP موجودًا بالفعل في ذاكرة التخزين المؤقت ClickOnce.لمزيد من المعلومات، راجع انقر مرة واحدة على الأمان والنشر.

قم بتكوين خدمة PresentationFontCache للبدء تلقائيًا

أول تطبيق WPF يتم تشغيله بعد إعادة التشغيل هو خدمة PresentationFontCache.تقوم الخدمة بتخزين خطوط النظام مؤقتًا وتحسين الوصول إلى الخطوط وتحسين الأداء العام.توجد تكاليف إضافية عند بدء تشغيل الخدمة، وفي بعض البيئات التي يتم التحكم فيها، فكر في تكوين الخدمة لتبدأ تلقائيًا عند إعادة تشغيل النظام.

تعيين ربط البيانات برمجياً

بدلاً من استخدام XAML لتعيين ملف DataContext تعريفيًا للنافذة الرئيسية، فكر في تعيينها برمجيًا في ملف قيد التنشيط طريقة.

نصائح أخرى

وووقت بدء تشغيل تطبيق WPF يمكن أن يكون أسرع بكثير إذا كنت تستخدم إطار 3.51 وليس 3.5 أو 3.0. 3.51 في الحقيقة تحسنا.

والنصيحة مفيدة للغاية في تحديد الأداء بدء التشغيل WPF رأيته أعطيت <لأ href = "https://stackoverflow.com/questions/2947118/wpf-slow-to-start-on-x64-in- الصافية للإطار 4-0 "> في هذا السؤال الآخر : تشغيل" تحديث منشئ الصورة الأصلية "في كل مجلد الإطار.

ويبدو أن مايكروسوفت لا يمكن أن تبقي مخبأ NGEN على ما يصل إلى التاريخ، والذي ينتج في التطبيق الخاص بك الى حد كبير اعادة تجميع نصف صافي الإطار كل بدء التشغيل واحد.

ومن الصعب الاعتقاد، ولكن يبدو أن يكون صحيحا.

هذا موضوع قديم، ولكن انتهى بي الأمر هنا عدة مرات أثناء محاولتي إصلاح مشكلة أداء بدء التشغيل مع تطبيقات WPF على نظام Win10 الخاص بي، لذلك اعتقدت أنني سأذكر إجابة قد تساعد الآخرين - إجابة تستغرق وقتًا طويلاً وقت بدء تشغيل رهيب يبلغ 5 ثوانٍ لجميع تطبيقات WPF على هذا النظام وصولاً إلى بضعة أجزاء من الثانية فقط. قم بإزالة برنامج التشغيل nVidia "3d Vision"..لدي بطاقة GeForce GTX 650، ولا يبدو أن برنامج التشغيل "3d Vision" يقدم أي شيء مفيد، لذا فإن إزالته لا تمثل مشكلة بالنسبة لي.ساعدت أداة تحليل الأداء VisualStudio2015 أخيرًا في إظهار أن كل وقت بدء التشغيل البالغ 5 ثوانٍ تقريبًا قد تم إنفاقه في وضع الخمول بعد الاتصال عبر nvapi64.dll - برنامج تشغيل nVidia.رائع.

ما ساعدني على أكثر من مادة ممتازة أن الروابط ستيوارت لكان خدعة XmlSerializer. أن حلق حقا حتى عدد غير قليل من ثانية. وعلاوة على ذلك لا يقلل من شأن تجزئة بك HD: -)

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