2009-10-06 8 views
2

J'écris une classe pour les événements de journalisation. My LogClass est implémenté en tant que singleton et n'importe quelle classe du système peut écrire une entrée de journal. Les entrées sont stockées dans une liste et lorsqu'un tampon est rempli, elles sont sauvegardées sur le disque.Conseils de sécurité du fil lors de l'utilisation de DataGridView et BindingList en C#

J'utilise un DataGridView pour afficher le contenu de la LogClass pendant l'exécution, donc j'ai utilisé BindingList pour que le Viewer se mette automatiquement à jour.

Je me demande comment mon fil est sûr. J'utilise "lock" chaque fois que j'ajoute une nouvelle entrée à la liste, et quand je suis en train de parcourir la liste pour la sauvegarder sur le disque. En plus de DataGridView, la classe est essentiellement en écriture seule car il n'y a pas d'option de lecture dans le journal, uniquement pour ajouter des entrées dans le journal. La sauvegarde est exécutée en interne, et c'est la seule fois où il y a une commande de lecture explicite sur BindingList.

Donc, ma vraie préoccupation est ce qui se passe avec DataGridView et BindingList? BindingList lève un événement chaque fois que la liste change. Cela ne semble pas être un problème lors de l'ajout de nouvelles entrées, car l'événement est levé lorsque l'ajout est terminé.

Mon code Dump() est la suivante:

lock (lockObj) { 
    foreach (LogEntry le in List) { 
     writeToDisk(le) 
     removeFromList(le) 
    } 
} 

Même si je suis le verrouillage de la liste pendant toute itération, un événement est jeté à la visionneuse que la liste a changé (en raison de la suppression) et donc être lu par le DataGridView. Je ne veux vraiment rien lire/écrire à la liste pendant que je la modifie. Des idées?

+0

http://stackoverflow.com/questions/1351138/bindinglist-listchanged-event –

+0

http://stackoverflow.com/questions/1351138/bindinglist-listchanged-event –

Répondre

1

Il n'y a pas vraiment une préoccupation car, une fois lié, vous pouvez uniquement modifier la liste à partir de la méthode Form.Invoke (héritée de Control.Invoke). Si vous essayez de modifier la liste à partir d'un autre thread, le runtime .NET aboie à votre w/une exception disant quelque chose à l'effet de "ne peut pas changer cette liste du fil actuel".

This a du code que vous pouvez récupérer.

Cordialement, = Alan

1

Je pensais que BindingList n'a pas implémenté de notification de changement. Dans ce scénario, je ne pense pas que ce soit thread safe.

La solution peut être d'utiliser une collection personnalisée qui implémente IBindingList et change l'accesseur de liste pour acquérir un verrou avant de retourner un élément.

J'ai une implémentation personnalisée de IBindingList avec notification de changement, donc si vous voulez, je peux partager. (Je vais probablement écrire un article sur le projet de code décrivant la mise en œuvre de toute façon ..)

Questions connexes