Lock generic list

Résolu
Signaler
Messages postés
118
Date d'inscription
lundi 16 février 2009
Statut
Membre
Dernière intervention
6 décembre 2010
-
Messages postés
118
Date d'inscription
lundi 16 février 2009
Statut
Membre
Dernière intervention
6 décembre 2010
-
Bonsoir,

Voila mon probleme. J'utilise dans mon application une List<MyClass>. Puis dans un evenement KeyDown je parcours cette collection et eventuellement j'execute une methode qui prend un certain temps.
Dans un evenement KeyUp, je retire evenutellement un item a cette mm liste. Ce qui fait que j'obtiens parfois une erreur, car ma liste est modifiée dans le keyup pendant qu'elle est parcouru dans le keydown (si le traitement est assez long).

ainsi il me faudrait je pensais locker, mais je ne vois pas vraiment comment faire pour y parvenir (enfin j'ai bien des idées mais pas convaincantes). Et je me disais que ce n'est pas très bon de lock pendant le parcourt de la liste, car ca aurait des consequences si le parcourt prend beaucoup de temps.

que me conseillez vous de faire dans ce cas?

RougailSaucisse

P.S: j'ai le mm probleme avec l'utilsation d'un dictionary.

10 réponses

Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Membre
Dernière intervention
20 juin 2013
59
Bonjour,
Un Enumerator ne peut pas voir sa collection être modifiée car il serait alors "perdu" au sein de l'enumeration.
La solution très simple consiste à passer par une boucle for à la place d'un foreach.

<hr />
-Blog-
-Site Perso-
Messages postés
860
Date d'inscription
jeudi 4 mars 2004
Statut
Membre
Dernière intervention
19 août 2014
29
Bonjour,

Je te conseille de recopier ta liste dans une même liste que tu utiliseras pour ton traitement.

Ou sinon, si je comprend bien ton besoin, tu souhaites supprimer l'item qui a été traité, non ?
Dans ce cas, pourquoi ne pas supprimer cet item à la fin du traitement et non à l'événement "OnKeyUp" ???

Bonne journée,

Billou_13
Bask En Force

--------------------------------------------------------------------
Connaître la réponse est une chose, savoir pourquoi en est une autre
---------------------
Messages postés
28
Date d'inscription
dimanche 24 août 2003
Statut
Membre
Dernière intervention
28 septembre 2009

Salut,

comment parcours tu ta List<> dans ton event KeyDown ?

CrougniMan
Messages postés
1860
Date d'inscription
lundi 28 novembre 2005
Statut
Membre
Dernière intervention
14 février 2015
50
Salut

Comme dit billou_13, si tu ne veux pas lock ta liste, duplique-la

Krimog :
while (!succeed = try()) ;
Messages postés
118
Date d'inscription
lundi 16 février 2009
Statut
Membre
Dernière intervention
6 décembre 2010
1
Salut et merci pour vos réponses.
J'avais effectivement une solution temporaire de copier la liste, ou de delay l'execution apres le parcourt du foreach mais bon je voulais etre sur qu'il n'y avait pas un moyen sans avoir besoin de faire de copie. Mais bon il semblerait finalement que c'est la meilleure solution. en revanche j'ai le même probleme avec un dictionary, ou la ca sera pas très fun de faire des copie a chaque fois mais bon.

Voici en gros ce que je souhaite realiser:

void HookManager_KeyDown(object sender, KeyEventArgs e)
{
if (touchesAppuyes.Count < ConfigKeys.MAXKEYS && !touchesAppuyes.Contains(e.KeyCode))
{
touchesAppuyes.Add(e.KeyCode);

dico.ToList().ForEach(
item =>
{
if (item.Value.EqualsValues(touchesAppuyes))
{
ExecuteAction(item.Key);
}
});
}
}

void HookManager_KeyUp(object sender, KeyEventArgs e)
{
if (touchesAppuyes.Count > 0 && touchesAppuyes.Contains(e.KeyCode))
{
touchesAppuyes.Remove(e.KeyCode);
}
}

Alors en gros dans le keydown j'ajoute la touche appuyée a une liste, que je compare à une autre liste (EqualsValue est une extension personelle, car je veux comparer les valeurs des items des listes et non si la "référence" est la mm).
Si ces deux listes sont egales alors j'execute une action (c'est cela qui prendra un certain temps).

Dans le keyup, lorsque je relache une touche il faut que je remove cette touche de la liste bien sur. Du coup si j'ai bien trouvé une action, et qu'elle met du temps a s'executer et que pendant ce temps je relache une touche, alors une exception sera levé car touchesAppuyes aura été modifiée pendant le parcours du foreach.

Voila et merci encore
Messages postés
118
Date d'inscription
lundi 16 février 2009
Statut
Membre
Dernière intervention
6 décembre 2010
1
RE bonsoir,

j'invalide temporairement les réponses car j'ai une question similaire.

private void MyFunction(int i)
{
//pour eviter les problemes d'acces concurrents à MainList
MyCollection temp = new MyCollection(MainList[i]);

foreach (MyClass myClass in temp)
AnotherFunction(myClass.PropA, 0);
}

Ici je fais donc une copie de ma liste "MainList" dans temp. Puis je parcours ma liste temporaire donc et j'execute une certaine action.
cependant si je fais des appels à MyFunction à intervalle de temps très rapide j'obtiens une erreur de "Collection was modified" sur mon foreach.
J'ai bien entendu d'autres fonctions ailleurs dans le code qui modifient "MainList", mais etant donné que je fais une copie avant de parcourir je ne comprend pas pkoi cette exception est levée.
Quelqu'un aurait-il une idée? j'ai loupé un truc la je pense...
Messages postés
118
Date d'inscription
lundi 16 février 2009
Statut
Membre
Dernière intervention
6 décembre 2010
1
Merci pour la réponse bidou, et effectivement en passant par une boucle for je n'ai plus d'exceptions bien que le comportement n'est pas celui attendu, mais la je pense que ca doit venir du reste de mon programme :/

Je comprends bien le probleme de n'enumerator mais en revanche je ne comprends toujours pas comment se fait-il que ma collection "temp" puisse etre modifiée puisque à part la parcourir dans mon foreach, je ne lui appliques aucune autre action. Comment se fait-il qu'elle puisse etre ainsi modifiée ?

(D'ailleurs je pense que c'est le fait que quelquepart - mais je ne comprend pas ou ni comment - elle est modifiée qui fait que mon programme ne se comporte pas exactement correctement).
Messages postés
118
Date d'inscription
lundi 16 février 2009
Statut
Membre
Dernière intervention
6 décembre 2010
1
Bon j'ai résolu mon probleme de comportement non attendu, qui etait bien du au fait qu'une de mes fonctions mettaient du temps a s'executer et que pendant ce temps je réexecutais cette même fonction et en gros ca faisait un beau bordel.

Du coup j'empeche la reexecution de la fonction si elle est en cours de traitement (une variable bool au debut de la fonction tout simplement).

Mais ma question demeure tout de mm a propos de la liste modifiée alors qu'a aucun endroit je n'ai de code la modifiant (je parle de la liste "temp" des exemples precedents). Si vous avez une idée ca serait sympa, et merci déjà pour l'aide apporté puisque au final j'ai pu trouver une solution tout de même.
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Membre
Dernière intervention
20 juin 2013
59
Bonjour,
Sans code, difficile d'aider... Essayes de poster une partie de code qui ne fonctionne pas.

<hr />
-Blog-
-Site Perso-
Messages postés
118
Date d'inscription
lundi 16 février 2009
Statut
Membre
Dernière intervention
6 décembre 2010
1
hum ca serait assez compliqué de poster tout ca. enfin bon merci pour l'aide quand mm, je posterai ma source bientot et a ce moment je vous ferez savoir les bugs connus.
Merci encore!