Question

J'ai une tête-scratcher sérieux sur mes mains ici. J'enquête sur les problèmes de performance avec un composant WPF dans notre application.

La demande de notre très grande, et des formes presque entièrement dans les fenêtres. Dans le cadre d'une nouvelle initiative, nous récrit l'un de nos composants de base avec un riche WPF ui. Il y a beaucoup de WinForms <->. WPF Interop passe avec cette chose à coller ensemble, et je pense que peut-être en quelque sorte lié à ce que je vois

Quand je profil le fonctionnement lent ANTS profileur, je vois beaucoup d'activités se déroulant dans la fonction UnsafeNativeMethods.IntGetMessageW. rapports ANTS AUtANt activité CPU y aller comme à l'ensemble de notre logique métier et WPF rendu des choses combinées. Il n'y a pas de code géré downline de cette fonction qui utilise les cycles, de sorte que tout IntGetMessageW fait il y a ce que je suis après.

Je ne suis pas particulièrement bien versé dans la programmation win32, mais je sais que les bases d'une boucle de message dans ce contexte. Rien de ce que je vois ici est que tout ce que nous faisons manuellement - à aucun moment dans notre code-nous interagir directement avec lui-même soit la MessageLoop sous-jacente, ou l'une des choses plus compliquées qui peut être consulté sur le répartiteur WPF.

Notre composante WPF en question est écrit ici héritant de la fenêtre (ie. Il est non seulement un contrôle / usercontrol), et nous montrons à l'aide ShowDialog de notre logique de niveau supérieur qui sert à appeler ShowDialog sur l'ancien WinForms version de ce composant. Il y a des contrôles WindowsFormsIntegrationHost que nous avons utilisés à l'intérieur du composant WPF pour préserver la compatibilité avec certains de nos pièces existantes qui ne pouvaient pas être réécrite en WPF.

J'ai fait des recherches pendant des jours, mais n'a jamais trouvé beaucoup à continuer. Je continue à trouver des messages vaguement apparentés qui parlent de messages d'entrée (souris et clavier), mais je ne sais pas ce que je peux faire pour vérifier que; Je l'ai déjà essayé le dépeçage du code pour supprimer toutes les opérations clavier / souris je pouvais.

Je vais avoir du mal à obtenir partout principalement parce que cette ligne de code est complètement isolé (pas un parent ou d'un enfant de tout ce que je peux signaler comme venant en fait de notre code), et complètement opaque sur ce qu'il fait.

Voici une image d'un graphe d'appel ANTS de la fonction ShowDialog montrant le chemin des appels pour obtenir ici: text alt

Je suis pleinement conscient que cela pourrait être quelque chose qui vient d'être fait dans le cadre de WPF (bien que d'autres que nous avons écrit un composant graphique WPF ne pas afficher ce comportement), ou que c'est juste un bug très étrange dans ANTS profileur , mais à ce point, je dois vérifier d'une manière ou d'une autre. Si quelqu'un peut me dire ce qui est ou pourrait se passer ici -. Ou me pointer vers une certaine façon, je serais en mesure de comprendre moi-même, je dirigerai toutes sortes de bon karma votre chemin

Mise à jour: En réponse à une discussion ci-dessous, voici une autre vue de ANTS - celui-ci illustre mieux la confusion que j'ai (ce qui est avec l'ANTS voir en mode « temps CPU »). Je suis partie de notre code censuré à la hâte, mais aucune des fonctions liées au système:

text alt

Merci pour la recherche!

Était-ce utile?

La solution

J'ai trouvé tout en recherchant des informations sur la même question. Je vais ajouter ce que je sais et voir si elle aide:

Je suis en cours d'exécution sur une boîte Windows XP - le cadre de WPF est plus intégré dans Vista et Win7 que dans XP. Certains de cela pourrait être dû à la façon dont WPF tourne « haut » du bureau de XP, plutôt qu'à l'intérieur.

Je suis en cours d'exécution d'une application WPF natif pur -. Sans WinForms ou tout autre code

Je couru dans cette essayer de déterminer pourquoi le défilement d'une fenêtre simplement consommerait 100% du CPU et bégayer tout en le faisant.

L'exécution du profileur de performance AQtime, je vois que IntGetMessageW occupe la plus grande partie de cette utilisation du processeur à 100%. Ce n'est pas dû à IntGetMessageW en attente d'un message, mais quelque chose que la fonction est en train de faire.

La encore une chose que je ne l'ai pas regardé en est que peut-être IntGetMessageW n'a jamais été une méthode rapide, et peut-être WPF surexploite simplement. Il est possible que les liaisons de données en WPF utilisent la pompe de message Win32 natif de mettre à jour des propriétés de dépendance au sein WPF. Si tel est le cas, il se pourrait que ma fenêtre a tout simplement trop de liaisons.

Autres conseils

Oui, ce qui est normal. Toute application GUI est toujours exécution GetMessageW (), en attendant que Windows pour envoyer un message. Il ne brûle pas réellement des cycles CPU faisant cela, juste bloqué sur un objet de synchronisation interne jusqu'à une sorte d'événement interface utilisateur est signalé.

Bien sûr, l'interface utilisateur rend difficile le profilage apps, vous avez vraiment besoin de tests unitaires qui testent les sous-composants de votre application.

Lorsque le profilage d'une application, vous devez faire la différence entre temps passé dans une méthode et cycles CPU consommée. De nombreux outils de profilage vous montrer la temps global passé dans une méthode - qui, dans le cas de somthing comme GetMessageW va être assez élevé. Toute l'activité du fil principal d'une application graphique apparaîtra à se produire dans cette méthode. Ce n'est pas nécessairement un problème, mais ... cela peut être simplement la pompe principale de message en attente sur un des objets de synchronisation et non en consommant des cycles.

Je vous suggère de commencer en utilisant la fonction d'échantillonnage dans les ANTS profileur pour identifier les méthodes qui sont appelées le plus souvent et corréler ceux des méthodes qui consomment le plus de cycles CPU. une fois que vous avez fait cela, vous décidez où votre instrument demande de plongée en plus loin et se faire une idée de ce que les graphiques d'appel ressemblent à des endroits qui sont les plus UC.

Vous devriez commencer par suspecter votre propre code d'abord. Il est rare que quelque chose comme l'infrastructure WPF ou Win32 est responsable de la mauvaise performance ou utilisation élevée du processeur. Probablement, le problème se situe quelque part dans votre mise en œuvre -. Il vous aide à obtenir un sentiment général où les cycles de CPU sont dépensés dans votre programme

Je suggère que vous passez aussi un peu de temps

L'appel graphique est un autre outil utile pour ANTS, car il vous aide à percer dans les zones du code qui sont les plus chers. La clé est de vous assurer que vous êtes à la recherche à la coût global et pas seulement le temps global .

text alt

On dirait que votre pompe de messages est de pompage beaucoup. Peut-être intéressant de voir quel genre de message que votre file d'attente de messages est rempli de. Peut-on utiliser Spy ++ sur votre fenêtre pour voir ce qui se passe?

Modifier

J'ai mal compris le problème.

Hans est juste Passant, votre programme attend juste à GetMessage pour un événement à traiter.

scroll top