لماذا سيأخذ GetMessagew استخدام وحدة المعالجة المركزية الضخمة في تطبيق WPF الخاص بي؟

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

سؤال

لدي خدش جاد على يدي هنا. أقوم بالتحقيق في مشكلات الأداء مع مكون WPF في تطبيقنا.

تطبيق .NET لدينا كبير جدًا ، بالكامل تقريبًا في نماذج Windows. كجزء من مبادرة جديدة ، أعدنا كتابة أحد مكوناتنا الأساسية باستخدام واجهة مستخدم WPF الغنية. هناك الكثير من winforms <-> wpf interop يحدث مع هذا الشيء لتغلبه معًا ، وأظن أنه قد يكون مرتبطًا بطريقة ما بما أراه.

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

أنا لست على دراية جيدة في برمجة Win32 ، لكنني أعرف أساسيات حلقة الرسائل في هذا السياق. لا شيء من ما أراه هنا هو أي شيء نقوم به يدويًا - في أي وقت من الأوقات في الكود ، نحن نتفاعل مباشرة مع Messageloop الأساسي نفسه ، أو أي من الأشياء الأكثر تعقيدًا التي يمكن الوصول إليها على مرسل WPF.

مكون WPF المعني هنا مكتوب وراثيًا من النافذة (أي. إنه ليس مجرد تحكم/UserControl) ، ونظهره باستخدام ShowDialog من منطقنا الأعلى الذي كان يستخدم لاستدعاء showdialog على إصدار WinForms القديم من هذا المكون. هناك بعض عناصر تحكم WindowsFormSintegrationhost التي استخدمناها داخل مكون WPF للحفاظ على التوافق مع بعض القطع الحالية التي لا يمكن إعادة كتابتها في WPF.

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

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

فيما يلي صورة لرسوم استدعاء النمل لوظيفة showdialog تُظهر مسار المكالمات للوصول إلى هنا:alt text

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

تحديث: استجابةً لبعض النقاشات أدناه ، إليك وجهة نظر أخرى من النمل - هذا واحد يوضح بشكل أفضل الارتباك الذي أواجهه (هذا مع عرض ANTS في وضع "وقت وحدة المعالجة المركزية"). لقد خضعت لأجزاء مراقبة على عجل من الكود لدينا ، ولكن لا يوجد أي من الوظائف المتعلقة بالنظام:

alt text

شكرا للبحث!

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

المحلول

لقد وجدت هذا أثناء البحث عن معلومات حول نفس المشكلة. سأضيف ما أعرفه وأرى ما إذا كان يساعد:

أنا أقوم بتشغيل مربع WinXP - إطار WPF أكثر دمجًا في Vista و Win7 مما هو عليه في XP. قد يكون بعض هذا بسبب كيفية تشغيل WPF "في الأعلى" من سطح المكتب XP ، بدلاً من داخله.

أقوم بتشغيل تطبيق WPF الأصلي النقي - مع عدم وجود winforms أو رمز آخر.

واجهت هذا في محاولة لتحديد سبب مجرد تمرير نافذة يستهلك بنسبة 100 ٪ وحدة المعالجة المركزية والتلعثم أثناء القيام بذلك.

تشغيل AQTime Performance Profiler ، أرى أن IntgetMessagew تشغل الجزء الأكبر من استخدام وحدة المعالجة المركزية بنسبة 100 ٪. هذا لا يرجع إلى انتباه intgetmessagew رسالة ، ولكن هناك شيء تقوم به الوظيفة بالفعل.

الشيء الوحيد الذي لم أتطلع إليه حتى الآن هو أنه ربما لم يكن IntgetMessagew طريقة سريعة ، وربما WPF يطغى عليه ببساطة. من الممكن أن تستخدم روابط البيانات في WPF مضخة الرسائل الأصلية لـ Win32 لتحديث خصائص التبعية داخل WPF. إذا كان هذا هو الحال ، فقد يكون نافذتي ببساطة تحتوي على الكثير من الروابط.

نصائح أخرى

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

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

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

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

يجب أن تبدأ بالشك في الكود الخاص بك أولاً. من النادر أن يكون هناك شيء مثل WPF أو Win32 للبنية التحتية المسؤولة عن ضعف الأداء أو استخدام وحدة المعالجة المركزية العالية. من المحتمل أن تكمن المشكلة في مكان ما في تنفيذك - فهي تساعدك على الحصول على إحساس عام بالمكان الذي يتم فيه قضاء دورات وحدة المعالجة المركزية في البرنامج.

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

alt text

يعد الرسم البياني للمكالمات أداة مفيدة أخرى في النمل ، حيث يساعدك على الحفر في مناطق من الكود الأكثر تكلفة. المفتاح هو التأكد من أنك تنظر إلى التكلفة الإجمالية وليس فقط الوقت الكلي.

alt text

يبدو أن مضخة الرسائل الخاصة بك تضخ الكثير. يمكن أن يكون من المثير للاهتمام معرفة نوع الرسالة التي تم ملء قائمة انتظار رسالتك. هل يمكنك استخدام Spy ++ على نافذتك لمعرفة ما يجري؟

يحرر

لقد أسيء فهم المشكلة.

Hans Passant على حق ، فإن برنامجك ينتظر فقط GetMessage لبعض الأحداث التي يجب معالجتها.

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