8
votes

Augmenter les performances de l'observaBlection WPF

actuellement, j'ai deux zones de liste WPF imitant les fonctionnalités suivantes

 Word 2007 personnaliser l'écran
(source: PSU.edu )

J'utilise 2 observationsCollections pour permettre aux utilisateurs de choisir les éléments dont ils ont besoin (la flexibilité est la clé ici). Le problème principal est que j'ai des milliers d'éléments regroupés dans les deux boîtes de liste. Tout dans l'ensemble de la conception fonctionne vraiment bien (avec quelques douzaines d'articles), mais mon stumage est lorsque un utilisateur copie tous les éléments disponibles de la gauche à droite lorsque l'écran gèle (heure à exécuter sur un fil différent?).

En regardant observablecollection Il manque une méthode AddRange et il existe différentes implémentations disponibles sur Internet. Je sais aussi que l'événement de collectionChanged est inutilement éjecté lorsque chaque article est copié sur des performances de drainage horriblement.

Il se peut que je dois permettre aux utilisateurs de choisir parmi des groupes de plus de 10 000 articles à l'avenir, ce qui ressemble à une mauvaise idée, mais n'est pas négociable que le regroupement sur la liste de la liste (Collectionviewsource) fonctionne vraiment bien , mais a l'effet secondaire de la commutation éteint la virtualisation des deux listboxes

Que puis-je faire pour améliorer les performances lors du chargement d'une liste de liste avec des milliers d'articles lors de la créature de la technologie à une observablecollection? Existe-t-il des implémentations de type Addrange que vous recommanderiez? Est le seul choix que j'ai ici pour exécuter ceci sur un fil d'arrière-plan qui semble cher parce que je ne charge pas de données d'une base de données?


4 Réponses :


1
votes

Vous pouvez probablement hériter de observablecollection (ou implémenter directement inotifidcollectionchangned ) pour ajouter beginUpdate et endupdate Méthodes. Modifications apportées entre les appels vers beginUpdate et endupdate serait en file d'attente, puis combinée dans une (ou plusieurs plages séparées) notifycollectionchangedeventargs objet qui serait être transmis aux gestionnaires de l'événement de collection lorsque endupdate est appelé.


2 commentaires

Autant que je sache, les contrôles WPF ne prennent pas en charge les mises à jour de la plage de la collecte et lancent une exception lorsqu'elles reçoivent plus de 1 article dans un événement de collectionChanged.


Wtf ?! Pourquoi fournir la possibilité de spécifier plusieurs éléments dans l'événement arguments s'ils ne le soutiennent pas? J'avais mis en œuvre la collection décrite dans ma réponse, mais n'avait pas eu le temps de le tester ... Je viens de le faire, et il semble que tu as raison :(. Donc, ma collection ne peut donc pas être utilisée pour des scénarios contraignants .. .



1
votes

Vous pouvez trouver une collection observable sur la sécurité du fil ici . Faites votre sécurité de la collection observable et liez-la à la liste de la liste.


2 commentaires

C'est l'approche que j'utilise et ça marche plutôt bien. Vous pouvez utiliser un travailleur d'antécédents pour remplir votre observaCollection et voir votre liste de liste étant peuplée à la volée.


Cette approche lance toujours un nombre déraisonnablement important d'événements sur le fil de l'interface utilisateur car chaque élément ajouté lancera sa propre collection modifiée. Cela ne va pas résoudre le problème.



2
votes

J'ai supprimé la collectionviewsource et le regroupement et les articles sont copiés en 1/2 une seconde, mais avec le regroupement de cela peut prendre une minute car la virtualisation ne fonctionne pas avec le groupement.

Je devrai décider d'utiliser la collectionviewsource


2 commentaires

La collectionViewsource fonctionne efficacement lorsque la liaison initiale a lieu, mais est très inefficace au moment de l'exécution. Je fais maintenant le tri / le filtrage dans le code derrière l'utilisation de Linq


Comment est-ce une réponse?



2
votes

Je ne pouvais pas résister à cela. Je ne pense plus que vous n'ayez plus besoin de cette réponse, mais peut-être que quelqu'un d'autre peut l'utiliser.

Ne pense pas trop difficile (ne pas approcher de cette multithreaded (cela fera des choses sujettes à l'erreur et inutiles. La plupart de la partie ennuyeuse est que si vous supprimez ou ajoutez 10000 articles, votre application (Listbox) sera très occupée avec la manipulation des événements soulevés par l'observaCollection. L'événement prend déjà en charge plusieurs articles. SO .....

Vous pouvez tamponner les objets jusqu'à ce qu'il modifie l'action. Ajoutez donc des actions seront tamponnées et que vous serez soulevés en tant que lot si «l'utilisateur» change d'action ou les rougira. Je ne l'ai pas testé, mais vous pouvez faire quelque chose comme ceci: xxx

amusez-vous !, J3R03N


2 commentaires

Cela ne fonctionne pas réellement. Lorsque vous essayez d'élever la collection Modification d'événement avec plusieurs articles, vous obtiendrez une notaupportedexception (les actions de portée ne sont pas prises en charge). Suggérez-vous à la recherche d'autres solutions telles que: binaireSculpting.com/2012/04/03/... ou peteohanlon.wordpress.com/2008/10/22/... , ou Stackoverflow.com/questions/670577/... .


En plus du commentaire de Jeroeon, l'observaBablecollection a une méthode oncollectionchangée que vous pouvez remplacer. Vous devez utiliser cela au lieu de vous abonner à l'événement de collection.