Faites vraiment attention avec les BitmapEffect

Lors d’une session de profiling CPU effectué durant une session de test de l’application
sous TSE, je me suis rendu compte que l’application sur certaines sessions utilisateurs
essayait de pomper 100% du CPU. Et avec grande surprise, quand j’ai demandé aux testeurs
s’ils effectuaient des traitements longs et couteux, certains m’ont indiqué que non
pas du tout, ils étaient juste devant une fenêtre qui affichait une petite grille
avec quelques lignes.

Après vérification, la fenêtre était très simple, et lorsque l’on ouvre ou ferme la
fenêtre le CPU passe d’aux alentours de 0% à 100% alors qu’aucun traitement n’est
censé se dérouler. Bien évidemment le problème n’a pas été détecté jusqu’à présent
puisqu’utilisé ailleurs que dans une session TSE, ce comportement n’est pas reproductible.

On passe donc doucement aux choses sérieuses, et ne connaissant pas encore correctement
l’application sur laquelle je travaille, je lance Snoop afin de trouver le nom de
la fenêtre incriminée et je commence mes premiers tests afin d’affiner ma réflexion
et mieux cibler les potentielles sources de problèmes.

Snoop est un utilitaire gratuit disponible
sur CodePlex
qui permet de parcourir agréablement l’arbre de contrôle de n’importe
quelle application WPF. Il permet, de plus, de modifier les propriétés de ces contrôles
afin de voir l’impact que cela peut avoir sur l’interface… et/ou le comportement de
l’application. Il s’agit d’un de mes outils préférés de debug d’applications WPF.

Et première piste, je me rends compte que si je collapse un des usercontrol présent
dans la fenêtre, le CPU continue d’être à un haut niveau mais baisse de manière assez
notable.

Rendez-vous donc dans le code de ce usercontrol, je me rends compte qu’il y a un backgroundworker
qui est utilisé, que beaucoup d’évènements sont déclenchés, mais pas de trace flagrante
d’un traitement bloquant.

Afin d’analyser plus finement le comportement de ce background worker, et de ces évènements
qui me semblent à première vue potentiellement louches, je me lance donc dans une
session de profiling CPU afin de pouvoir rapidement détecter le point qui pose problème.
J’utilise pour cela le profiler de Visual Studio 2008 Team Suite, et je compare les
résultats avec les résultats proposés par dotTrace.

Après avoir “nettoyé” plusieurs points ennuyeux qui parasitaient ma lecture du rapport
du profiler (essentiellement des appels de ressources I/O, réseau, etc. effectués
en synchrone), je commence à faire une grosse grimace en me rendant compte que le
CPU passe beaucoup de temps non pas à exécuter du code managé (ce qui m’aurait permis
de comprendre simplement où était l’erreur de développement) mais le passe à exécuter
du natif. Bref, ça sent vraiment pas bon, et d’un potentiel problème de développement
je me retrouve sur un problème qui risque d’être beaucoup plus compliqué à résoudre.

Etant dans une application WPF, il y a de bonnes chances que ce temps passé à exécuter
du natif soit du temps passé à exécuter du code lié à l’affichage. Je retourne donc
au sein de Visual Studio afin d’analyser le XAML du usercontrol que j’avais “spotté”
via Snoop et rien ne me choque, je remonte donc l’arbre de contrôle pour essayer de
trouver une piste, et je me rends compte que la fenêtre qui contient le usercontrol
n’a pas de bordure et à l’AllowTransparency d’activé. Ce sont des éléments potentiellement
couteux mais même désactivés le CPU ne souhaite toujours pas prendre de repos.

EasyDropShadowExamplesAlors
qu’une simple suppression du DropShadowEffect qui a été placé à l’intérieur de cette
fenêtre permet de passer d’une consommation de 100% à quelques % ! Et je dois bien
avouer que ce fut pour moi une vraie surprise, tout le monde sait que les
BitmapEffect sont lents et couteux comme je vous l’indiquais il y a presque 3 ans
,
mais de là à prendre 100% du CPU il y a quand même un pas… que WPF a franchi dans
certaines conditions sous TSE !

Conclusion de ce post mortem de séance de tests : Faites donc particulièrement attention
à l’utilisation des BitmapEffects si votre application doit être utilisé via TSE !

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *