Lock generic list

Résolu
RougailSaucisse Messages postés 118 Date d'inscription lundi 16 février 2009 Statut Membre Dernière intervention 6 décembre 2010 - 17 mars 2009 à 07:46
RougailSaucisse Messages postés 118 Date d'inscription lundi 16 février 2009 Statut Membre Dernière intervention 6 décembre 2010 - 18 mars 2009 à 16:22
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

cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
18 mars 2009 à 08:05
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-
3
billou_13 Messages postés 860 Date d'inscription jeudi 4 mars 2004 Statut Membre Dernière intervention 19 août 2014 29
17 mars 2009 à 09:51
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
---------------------
0
crougni77 Messages postés 28 Date d'inscription dimanche 24 août 2003 Statut Membre Dernière intervention 28 septembre 2009
17 mars 2009 à 12:50
Salut,

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

CrougniMan
0
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
17 mars 2009 à 15:24
Salut

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

Krimog :
while (!succeed = try()) ;
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
RougailSaucisse Messages postés 118 Date d'inscription lundi 16 février 2009 Statut Membre Dernière intervention 6 décembre 2010 1
17 mars 2009 à 19:43
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
0
RougailSaucisse Messages postés 118 Date d'inscription lundi 16 février 2009 Statut Membre Dernière intervention 6 décembre 2010 1
18 mars 2009 à 04:27
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...
0
RougailSaucisse Messages postés 118 Date d'inscription lundi 16 février 2009 Statut Membre Dernière intervention 6 décembre 2010 1
18 mars 2009 à 08:53
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).
0
RougailSaucisse Messages postés 118 Date d'inscription lundi 16 février 2009 Statut Membre Dernière intervention 6 décembre 2010 1
18 mars 2009 à 09:39
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.
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
18 mars 2009 à 13:53
Bonjour,
Sans code, difficile d'aider... Essayes de poster une partie de code qui ne fonctionne pas.

<hr />
-Blog-
-Site Perso-
0
RougailSaucisse Messages postés 118 Date d'inscription lundi 16 février 2009 Statut Membre Dernière intervention 6 décembre 2010 1
18 mars 2009 à 16:22
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!
0
Rejoignez-nous