Comment faire ObservableCollection thread-safe?
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
Je suis d'ajout/suppression d'une ObservableCollection qui n'est pas sur un thread d'INTERFACE utilisateur.
J'ai une méthode noms EnqueueReport à ajouter à la collection et un DequeueReport supprimer de la collection.
Le flux d'étapes est comme ci-dessous :-
- 1.appel EnqueueReport chaque fois qu'un nouveau rapport est demandé
- appeler une méthode toutes les quelques secondes pour vérifier si le rapport est généré (ce qui a une boucle foreach qui vérifie l'généré le statut de tous les rapports ObservableCollection)
- appel DequeueReport si le rapport est généré
Je ne suis pas beaucoup plus dans les bibliothèques visual C#. Quelqu'un peut-il svp me guider sur ce?
Essayez celui-ci ObservableCollection et enfilage
Avec la .net framework, vous ne pouvez pas lier à une Collection Observable et puis le modifier à l'extérieur de la thread de l'INTERFACE utilisateur. Il y a quelques modèles autour, y compris des différés de la mise à jour de l'INTERFACE utilisateur, des insertions ou de la création d'un thread-safe de la classe de mise en œuvre de CollectionView.
Avec la .net framework, vous ne pouvez pas lier à une Collection Observable et puis le modifier à l'extérieur de la thread de l'INTERFACE utilisateur. Il y a quelques modèles autour, y compris des différés de la mise à jour de l'INTERFACE utilisateur, des insertions ou de la création d'un thread-safe de la classe de mise en œuvre de CollectionView.
OriginalL'auteur ilight | 2014-04-16
Vous devez vous connecter pour publier un commentaire.
Vous pouvez créer un simple thread version imprimable de la collection observable. Comme suit :
avec ça maintenant faire un énorme rechercher & remplacer et changer tous vos
ObservableCollection
àMTObservableCollection
et votre bon allerEn général, vous ne serait pas faire un thread d'écriture/ajouter directement dans un non filetée de l'objet. Vous pouvez utiliser un progrès de l'événement pour mettre à jour les informations de thread lorsque de nouveaux éléments sont en cours de traitement et prêt à recueillir. Alors le thread principal peut appeler de manière asynchrone à l'insertion de l'élément dans la liste. Cette liste ne asynchrone mise à jour via le répartiteur. Mais je ne sais pas comment vous l'avez utilisé, mais je l'utilise de façon intensive et je ne cesse de pousser et tirer 2 250 2,525 articles par secondes avec 25 threads en cours d'exécution sur elle. chaque pousser ou tirer des entre 90 et 101 articles par secondes. Elle fonctionner 24/7 et toujours pas de problème.
Ah OK, je vois... donc, fondamentalement, vous êtes seulement à l'écriture à partir d'un fil, un autre de l'INTERFACE.
Ce n'est pas thread-safe, tout ce que vous avez à faire est de basculer vers le thread d'INTERFACE utilisateur / Dispatcher. Ne pas faire de la collecte de thread-safe.
Pas thread-safe, mais il n'répondre à l'OP de la question. Peut-être que la question devrait être ré-intitulé "Comment ajouter en toute sécurité à un Thread d'INTERFACE utilisateur de l'ObservableCollection à partir d'un autre thread". De toute façon, c'est ce que je cherchais quand j'ai cherché pour le "thread-safe observablecollection".
OriginalL'auteur Franck
La solution Franck posté ici dans le cas où un thread est d'ajouter des choses, mais ObservableCollection lui-même (et la Liste, il est basé sur l') ne sont pas thread-safe. Si plusieurs threads sont écrit à la collecte, dur-à-piste-aux bogues pourraient être introduits. J'ai écrit une version de ObservableCollection qui utilise un ReaderWriteLockSlim pour être vraiment thread-safe.
Malheureusement, il a frappé les StackOverflow limite de caractères, si elle est ici sur PasteBin. Cela devrait fonctionner à 100% avec de multiples lecteurs/écrivains. Comme des ObservableCollection, il est invalide à modifier la collection dans un rappel de celui-ci (sur le thread qui a reçu le rappel).
Je pense que la version que j'ai mis en place avant n'a pas compiler, et mis en ligne une nouvelle qui ne fait pas référence interne les fonctions de l'utilitaire.
Haha, je le fais aussi. Pas de soucis.
Il a travaillé comme un charme! Merci!
N'est-il pas mieux de le mettre sur gist.github.com?
OriginalL'auteur Robert Fraser
Comme de .net framwork 4.5 vous pouvez utiliser natif de la collection de la synchronisation.
BindingOperations.EnableCollectionSynchronization(YourCollection, YourLockObject);
YourLockObject
est instance d'un objet quelconque par exemplenew Object();
. Utiliser un par collecte.Ceci élimine le besoin d'une classe spéciale ou quoi que ce soit. Il suffit d'activer et de profiter 😉
PS:
BindingOperations
réside dans l'espace de NomsSystem.Windows.Data
.Grand. Cela devrait être accepté de répondre.
OriginalL'auteur FastJack
Vous pouvez utiliser un ObservableConcurrentCollection classe. Ils sont dans un package fourni par Microsoft dans les Extensions Parallèles Extras de la bibliothèque.
Vous pouvez l'obtenir prédéfinis par la communauté sur Nuget:
https://www.nuget.org/packages/ParallelExtensionsExtras/
Ou l'obtenir à partir de Microsoft ici:
https://code.msdn.microsoft.com/ParExtSamples
ObservableConcurrentCollection a un peu des fonctionnalités limitées. Beaucoup mieux la mise en œuvre est ici codeproject.com/Articles/64936/...
OriginalL'auteur Greg