IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

thread collections (ArrayList) et synchronisation


Sujet :

C#

  1. #1
    Isher
    Invité(e)
    Par défaut thread collections (ArrayList) et synchronisation
    Bonjour,

    Je dois travailler sur un ArrayList qui peut être lu et/ou mis à jour ds plusieurs thread. La documentation Microsoft propose plusieurs solutions.
    Une première est de récupérer un "wrapper" avec ArrayList.Synchronized

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ArrayList myWrapper = ArrayList.Synchronized(myList)
    foreach((Object item in myWrapper){
     
    }
    et une autre de faire un lock(myList.SyncRoot) suivi d'un foreach.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ArrayList myCollection = new ArrayList();
      lock(myCollection.SyncRoot) {
      foreach (Object item in myCollection) {
      // Insert your code here.
      }
     }
    J'ai ecrit le 1er exemple, est-il thread-safe? Si oui en quoi diffère-t-il du second (tiré de la doc Microsoft)

    Le traitement pour chaque élément de la Collection est assez long, cela va-t-il ralentir de maniere significative le reste du programme?

  2. #2
    Membre émérite Avatar de ppphil
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    617
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2007
    Messages : 617
    Par défaut
    Je ne sais pas répondre à toutes tes questions. Une chose dont je suis sur, c'est que tu ne peux pas faire un foreach sur un liste synchronisée. Si durant ton foreach un autre thread modifie ta liste, l'énumération du foreach génèrera une erreur. Expérience faite, si tu utilise un for tu n'as plus ce problème.
    Si tu utilise un lock, aucun thread ne pourra accéder à ta liste tant que tu ne la libère pas.
    La liste synchronisée permet à plusieurs threads d'y accéder "simultanément"

  3. #3
    Membre Expert Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Citation Envoyé par ppphil Voir le message
    Expérience faite, si tu utilise un for tu n'as plus ce problème.
    Certes, mais on a un problème autrement pire : si un autre thread fait liste.Clear() alors que tu es en train de la parcourir dans un for, on a un risque de faire liste[i] et de sortir des limites de la liste( OutOfBoundException !). Donc for marche 99% du temps, mais est tout aussi sujet à bug, et même sujet à des bugs bien pires car plus imprévisibles Au moins foreach pète une exception plus souvent.

    J'ajoute aussi que le concept de Synchronized a disparu avec les collections de System.Collections.Generics, ce qui incite à croire qu'utiliser un wrapper Synchronized n'est plus la façon préconisée de faire.

    Désolé si j'apporte aucune réponse à la question dans mes projets, je locke à chaque lecture ou écriture les listes manipulées par plusieurs threads, mais cette solution n'est pas valable dans tous les cas.

  4. #4
    Isher
    Invité(e)
    Par défaut
    Merci a vous 2 pour vos réponses qui m'éclairent tout de même sur les sections critiques.

    Citation Envoyé par Guulh Voir le message
    Certes, mais on a un problème autrement pire : si un autre thread fait liste.Clear() alors que tu es en train de la parcourir dans un for, on a un risque de faire liste[i] et de sortir des limites de la liste( OutOfBoundException !).
    Et si au lieu de retirer des éléments, on en rajoute, que se passe-t-il? dans un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ArrayList myWrapper = ArrayList.Synchronized(myMist);
    for(int i=0; i < mywrapper.Count; i++) {
     
    }
    par exemple.

  5. #5
    Membre émérite Avatar de ppphil
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    617
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2007
    Messages : 617
    Par défaut
    Oui, t'as raison Guulh, on peut aussi traiter la liste, à l'intérieur du for, dans un try catch.
    Mais de toutes façons il faut bien savoir que quand on accède à une liste sans la bloquer on a des données qui peuvent ne pas être cohérentes tout dépend de ce qu'on attend des valeurs de cette liste.

    Pour ce qui est de savoir ce qui se passe si on ajoute des items dans un thread alors que l'on parcoure la liste dans un autre, il suffit d'essayer (avec des timers, des sleep et tout le bataclan...)

  6. #6
    Isher
    Invité(e)
    Par défaut
    Bon j'ai fait qqs tests comme l'explique ppphil et cela semble fonctionner mais j'avoue une certaine "anxiété" à la mise en prod meme si tout marche correctement pdt les tests

    Merci pour vos réponses qui m'ont tout de meme bien aiguillé.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 7
    Dernier message: 14/07/2011, 22h58
  2. Réponses: 1
    Dernier message: 26/08/2009, 08h52
  3. les collections Arraylist
    Par laredo dans le forum Débuter
    Réponses: 2
    Dernier message: 19/09/2008, 17h35
  4. [C#] Collections (ArrayList)
    Par webspeak dans le forum Windows Forms
    Réponses: 7
    Dernier message: 06/04/2005, 14h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo