8
votes

Problèmes de performance initializEcomponant WPF

J'ai une application WPF (.NET 4) qui a une fenêtre principale, et à l'intérieur de cette fenêtre principale affiche de nombreux USERCONTROLS . Diverses actions effectuées par l'utilisateur provoquent le usercontrols qui sont affichés pour être remplacés par différents autres contrôles avec différentes données.

Je suis cependant dans les problèmes de performances, cependant, lors de la commutation de ces commandes. Le thread de Dispatcher WPF passe à 100% de la CPU lors du chargement des commandes. Sur les machines plus anciennes, ou avec un grand nombre de commandes, cela peut entraîner une application qui semble verrouillée jusqu'à 30 secondes!

Profilage indique que la quasi-totalité de ce temps de CPU est consacrée à appeler les diverses méthodes d'initialisation initializececomponent de tous les différents USERCONTROLS - Aucun contrôle de personne ne semble être considérablement pire que tout autre , ils semblent tous prendre entre 0,2 et 0,5 seconde (sur ma machine de développement avec un processeur rapide et une bonne carte graphique).

Aussi loin que je sache, initializececomponent est où WPF charge effectivement la xaml compilée dans la mémoire.

Je suis une perte pour quoi faire ici. Je voudrais pré-initialiser les choses sur un fil d'arrière-plan, mais toutes les commandes WPF doivent être créées et utilisées sur le fil du répartiteur, donc je ne pense pas que cela soit possible.

Sinon, il semble que les seules options que j'ai sont de supprimer tout mon XAML ??

Toute aide serait grandement appréciée


2 commentaires

Sans en savoir plus sur votre application (détails spécifiques + code), je ne peux que vous imaginer que vous avez une énorme quantité de contrôles utilisateur (+50) et / ou de liaisons de données très lourdes. Donc, la seule réponse serait de redéfinir votre logique d'application. Ce que vous devez également comprendre, c'est que WPF est absolument de la merde lorsqu'il s'agit de grandes quantités de commandes / données, car il est fortement impêté (je suppose que c'est trop élevé d'un cadre). Peut-être essayez peut-être Winforms pour votre application (qui est un peu meilleur) ou écrivez tout dans Native C ++ / DirectX (a'la Photoshop, style AutoCAD)


Jeremiahmorrill.WordPress .COM / 2011/02/14 / ... - Je suppose que les contrôles sont chargés, le rendu généré et peut-être mis en cache. Il mentionne PIX (un outil de PARF WPF) que vous aimerez peut-être essayer.


3 Réponses :


0
votes

La méthode initializececomponent prend du temps car elle doit insérer le contrôle de l'arborescence visuelle / logique et assurer toutes les liaisons, thèmes, ressources attendues, etc.

Ma seule suggestion est - est-il possible d'initialiser tous les contrôles potentiels dès le départ, puis de l'afficher / masquez-les si nécessaire à l'aide de la propriété Visibilité ?

Vous pouvez utiliser congéloire pour la mise en cache de certaines interfaces d'interface utilisateur, mais s'ils sont des contrôles utilisateur, vous voudrez probablement que votre utilisateur interagisse avec eux.


1 commentaires

Merci pour la réponse, mais nous avons initialement chargé toutes les commandes à l'avance, puis montrant ceux dont nous avons besoin. Ensuite, il y avait un décalage gigantesque (plus d'une minute sur des machines plus lents) lorsque la forme a été montrée d'abord, ce qui était une expérience utilisateur encore pire que le comportement actuel :-(



3
votes

Pour revoir cela - nous avons de nombreux contrôles complexes à l'écran, mais nous ne pouvons pas simplement vous en débarrasser pour garder le WPF heureux!

Une autre expérimentation avec profilage a montré que l'utilisation de commandes personnalisées (fondamentalement, une classe C # dérive directement à partir de Contrôle et définissant l'interface utilisateur dans un fichier generic.xaml Le fichier thèmes semble seulement Encourcir le coup de chargement et l'analyse de la xaml une fois. Par la suite, chaque contrôle applique simplement le thème préexistant.

Les contrôles personnalisés sont beaucoup plus difficiles à travailler avec des utilisateurs, mais cela semblait aider à obtenir beaucoup de performances de charge.


0 commentaires

0
votes

Pour l'enregistrement, j'ai eu une fenêtre avec une durée de charge d'environ 1500 ~ 2000 ms, le problème était le problème des icônes .

J'utilisais un outil pour convertir SVG en éléments de DayingImage XAML et un contrôle utilisateur avec un grand dictionnaire de ressources avec une image de dessin pour chaque icône utilisée

L'initializecomonent était si lent car il devait analyser ce grand fichier XAML contenant toutes les données vectorielles pour les images

J'espère que cela aide.


0 commentaires