Strange "La collection a été modifiée après l'instanciation de l'énumérateur" exception
Peut-être que quelqu'un peut me pointer dans la bonne direction, parce que je suis complètement perplexe sur ce.
J'ai une fonction qui imprime simplement une LinkedList de classes:
LinkedList<Component> components = new LinkedList<Component>();
...
private void PrintComponentList()
{
Console.WriteLine("---Component List: " + components.Count + " entries---");
foreach (Component c in components)
{
Console.WriteLine(c);
}
Console.WriteLine("------");
}
La Component
objet a fait un custom ToString()
appel en tant que tel:
int Id;
...
public override String ToString()
{
return GetType() + ": " + Id;
}
Cette fonction fonctionne généralement beaux - cependant, je ai couru dans la question que lorsqu'il construit à environ 30 ou alors, les entrées dans la liste, le PrintcomplentList
foreach
déclaration revient avec un InvalidOperationException: Collection was modified after the enumerator was instantiated.
Maintenant, comme vous pouvez le voir je ne suis pas de modifier le code dans la boucle for, et je n'ai pas explicitement créé les fils, bien que ce soit à l'intérieur d'un XNA environnement (si c'est important). Il convient de noter que l'impression est assez fréquent que la sortie de la Console est de ralentir l'ensemble du programme.
Je suis complètement perplexe, est-ce quelqu'un d'autre de cette?
source d'informationauteur cyberconte
Vous devez vous connecter pour publier un commentaire.
Je soupçonne l'endroit pour commencer la recherche sera à tous les endroits où vous manipuler la liste - c'est à dire insérer/supprimer/ré-affecter les postes. Je soupçonne qu'il y aura un rappel/même-gestionnaire de quelque part qui est de se faire licencier de manière asynchrone (peut-être dans le cadre de la XNA peinture etc boucles), et qui est l'édition de la liste - essentiellement à l'origine de ce problème comme une condition de course.
Pour vérifier si c'est le cas, mettre quelques debug/sortie de trace à travers les lieux que manipuler la liste, et voir si elle a jamais (et en particulier, juste avant l'exception) exécute le code de manipulation en même temps que votre sortie de la console:
Malheureusement, de telles choses sont souvent une douleur à déboguer, que de changer le code pour enquêter sur il change souvent le problème (une Heisenbug).
Une réponse serait de synchroniser l'accès; c'est à dire dans tous les lieux que modifier la liste, utilisez un
lock
autour de l'opération complète:et dans votre callback (ou autre)
En particulier, une "opération complète" peut inclure:
foreach
/for
(c'est à dire non à l'individu/opérations distinctes - mais les unités de travail)
Au lieu de
foreach
j'utilisewhile( collection.count >0)
ensuite utilisercollection[i]
.Je ne sais pas si c'est pertinent pour l'OP, mais j'ai eu le même message d'erreur et trouvé ce fil au cours d'une recherche sur google. J'ai été en mesure de le résoudre par l'ajout d'une pause après la suppression d'un élément dans la boucle.
Si vous laissez de côté la pause, vous recevrez le message d'erreur "exception InvalidOperationException: Collection a été modifiée après l'agent recenseur a été instancié."
À l'aide de Pause pourrait être un moyen, mais il peut avoir un impact sur votre série de l'opération.
Ce que je fais dans ce cas simplement convertir le foreach traditionnel pour la boucle
Cela fonctionne sans aucun problème.