2 votes

Echanger les éléments de BindingList<SomeClass> prend beaucoup de temps, pourquoi est-ce le cas et que devrais-je faire?

Je suis en train d'écrire une petite application en C# principalement pour le plaisir, et il y a un DataGridView pour afficher des données, il est lié à BindingList. Le plaisir a commencé à partir du moment où j'ai décidé de rendre le tableau triable, c'est la raison pour laquelle j'utilise BindingList. Autant que je sache, il n'y a pas de mise en œuvre standard de cela dans BindingList, mais msdn a l'article qui en parle (sur l'implémentation du tri et de la recherche pour BindingList). En résumé, quelques lignes de leur implémentation qui posent problème:

SomeClass tmp;
for(...)
{
    tmp = this[i]; //rapide
    this[i] = this[position]; // lent
    this[position] = tmp; // lent
}

Comme le montrent les commentaires, la première attribution ne prend pas beaucoup de temps, mais les deux autres sont vraiment lentes. Je ne parviens pas à comprendre la raison derrière cela, mais à cause de cela, le tri de la liste d'environ 50 éléments prend environ deux secondes. Eh bien, je peux utiliser une solution de contournement, mais cela semble un peu moche. De plus, je veux vraiment savoir ce qui cause un tel comportement.

2voto

Knaģis Points 9927

Le ralentissement se produit parce que l'attribution va entraîner le redessin de tout ce qui est lié à cette liste (par exemple, le DataGridView).

Vous devriez modifier votre méthode de tri pour désactiver la levée d'événements pendant que la liste est modifiée.

var origRaiseEvents = this.RaiseListChangedEvents;
this.RaiseListChangedEvents = false;
try
{
    // voici votre code original.
}
finally
{
    this.RaiseListChangedEvents = origRaiseEvents;
}

1voto

Reed Copsey Points 315315

Le principal problème, s'il s'agit d'un BindingList, est que le DataGridView va essayer de se mettre à jour chaque fois que vous définissez quoi que ce soit dans votre BindingList. Cela signifie que les deux lignes que vous avez marquées comme lentes ne sont probablement pas lentes elles-mêmes, mais lentes parce qu'elles déclenchent le rafraîchissement du DataGridView, ce qui signifie qu'il se rafraîchit de nombreuses fois pendant l'opération de tri.

Vous pourriez contourner cela en encapsulant le BindingList au lieu de le sous-classer, et en ne déclenchant pas les événements pendant le tri, mais en attendant que le tri soit terminé, puis rafraîchir l'intégralité de la liste.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X