C# la prévention de la Collecte a Été Modifié exception
Ne
foreach(T value in new List<T>(oldList) )
est dangereux (coûteux) lorsque oldList contient 1 millions de T objet ?
Plus généralement quelle est la meilleure façon de les énumérer sur oldList donné que des éléments peuvent être ajoutés/supprimés lors de l'énumération...
Il semble comme il y a deux questions différentes ici. Je ne sais pas pourquoi ils ont été combinées.
OriginalL'auteur Toto | 2011-02-15
Vous devez vous connecter pour publier un commentaire.
La règle générale est que vous ne devez pas modifier de la même collection dans laquelle vous énumérez. Si vous voulez faire quelque chose comme ça, de garder l'autre collection qui permettra de garder une trace des éléments à ajouter/supprimer de la collection d'origine, puis après la sortie de la boucle, effectuer l'ajout/suppression de fonctionnement sur la collection d'origine.
Comme mentionné dans ma réponse mis à jour, si vous êtes en utilisant .NET 4.0, pensez à utiliser les Collections Simultanées.
OriginalL'auteur Sachin Shanbhag
J'ai l'habitude de simplement créer une liste de tous les objets à retirer ou à ajouter.
Dans le
foreach
je viens d'ajouter les éléments à la appropriée de collections et de modifier l'original de la collection après leforeach
ont terminé en boucle (par le biais de laremoveItems
etaddItems
collection)OriginalL'auteur Dirk Trilsbeek
tout comme ce
OriginalL'auteur MacX
Si vous voulez dire que vous pouvez ajouter/supprimer des objets à partir d'un autre thread, je voudrais:
1-synchroniser les threads
2 - dans ajouter/supprimer des threads, créer une liste d'éléments à ajouter ou de supprimer des
3 - et puis supprimer ces articles dans une section critique (si elle est petite, vous n'avez pas à synchroniser tout en ajoutant les éléments pour la supprimer de la liste)
Si vous ne voulez pas le faire, vous pouvez utiliser à la place de foreach, qui permettrait d'éviter que l'exception, mais vous devez prendre des précautions supplémentaires afin de ne pas obtenir d'autres types d'exceptions
Je suis heureux de vous aider. Si c'était la solution à votre problème, pourriez-vous s'il vous plaît marquer comme réponse, en cliquant dans le "chèque vert signe"? 🙂 merci!
OriginalL'auteur JSBach
Si vous utilisez la boucle Foreach pour la modification de collection, alors vous obtiendrez cette erreur comme ci-dessous.
Solution - l'usage De la Boucle comme ci-dessous.
OriginalL'auteur Bhanu pratap
Vous pourriez parcourir la liste sans l'aide d'un agent recenseur, donc faire quelque chose comme...
Je vous boucle vers l'arrière vous avez un problème avec l'ajout d'éléments.
La condition de fin de boucle est évaluée à chaque iteratin ou juste une fois ?
La condition de fin sera évaluée à chaque itération.
vrai, j'ai raté l'ajout d'une partie de la question.
OriginalL'auteur Nick Jones
Pour moi, la première chose que vous devriez envisager d'utiliser une sorte de pagination de données, car la présence de ces 1-million-articles-grande liste pourrait être dangereux lui-même.
Avez-vous entendu parler du motif d'Unité de Travail?
Vous pouvez la mettre en œuvre afin de vous marquer des objets pour créer, mettre à jour ou de les supprimer, et plus tard, vous appelez "SaveChanges", "Commit" ou tout autre faire le travail de l' "appliquer les changements", et vous aurez fait.
Par exemple, vous itérer sur les énumérable (oldList) et vous les marquer comme "supprimer". Plus tard, vous appelez "SaveChanges" et la plus abstraite, générique de l'unité de travail va se répéter sur la petite, filtré la liste des objets à travailler avec.
De toute façon, éviter les listes d'un million d'articles. Vous devez travailler avec paginée des listes d'objets.
OriginalL'auteur Matías Fidemraizer
Il sera "lent", mais il n'y a pas beaucoup plus que vous pouvez faire à ce sujet, sauf qu'il tourne sur un thread d'arrière-plan. E. g. à l'aide d'un BackgroundWorker.
Si vos opérations sur la liste ne se produit que sur un fil, la bonne approche est d'ajouter les articles à ajouter/supprimer pour séparer les listes, et d'effectuer ces opérations à l'issue de votre itérations a fini.
Si vous utilisez plusieurs threads, vous devez regarder dans la programmation multithread, et l'exemple de l'utilisation les verrous ou probablement mieux un ReaderWriterLock.
Mise à JOUR:
Comme mentionné dans un autre Un Débordement de pile question, c'est désormais possible, sans aucun effort .NET 4.0 lors de l'utilisation simultanée des collections.
OriginalL'auteur Steven Jeuris
foreach(T valeur dans la nouvelle Liste(oldList).ToList() ) - essayez de donner une
OriginalL'auteur iq.psb
vous pouvez utiliser un drapeau pour passer à la modification temporaire de la liste alors que l'original est énuméré.
///où vous énumérez
///où vous êtes en train de modifier lors de l'énumération
OriginalL'auteur Vijay Babu