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 :

[C#] ArrayList, For each et threads


Sujet :

C#

  1. #1
    Futur Membre du Club
    Inscrit en
    Octobre 2006
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 17
    Points : 7
    Points
    7
    Par défaut [C#] ArrayList, For each et threads
    Bonjour tout le monde!

    Alors voilà, j'ai un petit problème avec les array list et mes threads.

    L'idée c'est que dans mon programme, j'affiche des graphes contenant des données extraites après traitement d'images.
    Donc mon prog capture les images à rythme constant et quand une image est traitée on déclenche un event qui envoie aux graphes les points à tracer en temps réel pour actualiser les graphes.

    Le programme est fait de façon que les points du graphes sont stockées dans un array list, que je parcours avec un for each pour tracer mon graphe.

    Le problème c'est que je me prends de temps en temps et de manière aléatoire une erreur: "Collection was modified; enumeration operation may not execute".

    Ce qui me parait assez logique puisque pendant qu'il lit mon array list, il y a de grandes chances que des données arrives et soient placées dedans.

    Après avoir chercher sur le net, j'ai vu qu'il y avait des méthodes de synchronisation, mais ça ne donne rien, quelqu'un aurait une idée?

    Voilà le code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    public void Draw(Graphics generalGraphs, Point ptOffset)
    {
                float x, y, x0, y0;
                Pen BluePen = new Pen(Color.Blue, 2);
     //...
                //draw chart data
                datapoint prevPoint = new datapoint();
     
                        foreach (datapoint myPoint in chartValuesSync)
                        {
                                x0 = ChartWidth * (prevPoint.x - graphOriginX) / graphScaleX + ChartInset;
                                y0 = graphHeight - (ChartHeight * (prevPoint.y - graphOriginY) / graphScaleY + ChartInset);
     
                                x = ChartWidth * (myPoint.x - graphOriginX) / graphScaleX + ChartInset;
                                y = graphHeight - (ChartHeight * (myPoint.y - graphOriginY) / graphScaleY + ChartInset);
     
                                if (y0 != (graphHeight - (ChartHeight * (0 - graphOriginY) / graphScaleY + ChartInset)))
                                {
                                    g.DrawLine(BluePen, x0, y0, x, y);
                                }
     
                            prevPoint = myPoint;
                        }
                }
                    generalGraphs.DrawImage(b, ptOffset.X, ptOffset.Y);
    }
    J'ai aussi une fonction setValue pour mettre une valeur dans le arraylist depuis l'extérieur.

    J'ai essayé d'ajouter un:
    ArrayList chartValuesSync = ArrayList.Synchronized(chartValues);
    Puis de prendre les valeurs là-dedans mais ça donne toujours l'erreur.

    De même avec un :
    lock (chartValuesSync.SyncRoot)
    avant de rentrer dans le if.

    Voilà, en espérant avoir été clair et que quelqu'un pourra m'aider,
    bye

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2003
    Messages : 835
    Points : 1 046
    Points
    1 046
    Par défaut
    Salut,

    Pour synchroniser tu peux effectivement utiliser l'instruction lock, mais il faut le faire pour le code de lecture comme celui d'écriture et sur un même objet. Pour des explications détaillées (en anglais) tu peux regarder ici. Un autre idée serait peut-être de travailler dans ta boucle sur une copie de ton array, l'insertion ayant lieu sur l'original.

  3. #3
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Points : 6 334
    Points
    6 334
    Par défaut
    Un ReaderWriterLock devrait répondre à ton besoin.
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

  4. #4
    Futur Membre du Club
    Inscrit en
    Octobre 2006
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 17
    Points : 7
    Points
    7
    Par défaut
    Ok, le ReaderWriterLock à l'air de bien marcher, je n'ai plus d'erreurs!

    Cependant d'après ce que j'ai lu sur internet, les ReaderWriterLock peuvent être un peu lent et ralentir les programmes.
    Qu'en est-il?
    Car disons que pour mon application, le temps d'exécution est assez important (beaucoup de traitement d'images avant cette étape).

    Pour info, sur cette ressource, je tourne à environ 50 lectures et 50 écritures secondes (autant de lectures que d'écritures).

    Juste au cas où il y ait des méthodes plus rapides, je suis preneur

    Merci bien en tout cas, le problème est résolu pour le moment

    a+

  5. #5
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Points : 6 334
    Points
    6 334
    Par défaut
    ça ralentit effectivement mais c'est simplement une conséquence de l'accès exclusif à la ressource. Tu peux avoir autant de lecteurs que tu souhaites en même temps, mais les écrivains ont un accès exclusif à la ressource (ecrivain par écrivain). Donc forcément quand tu écris dans ta liste, les lecteurs sont mis en attente pour garantir des lectures cohérentes.
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

  6. #6
    Futur Membre du Club
    Inscrit en
    Octobre 2006
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 17
    Points : 7
    Points
    7
    Par défaut
    Oki, c'est compris, merci bien pour les explications, c'est plus clair maintenant.
    a+

  7. #7
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 195
    Points
    5 195
    Par défaut
    salut

    si je peux me permettre une intervention....

    Une autre solution qui me parait "moins" pénalisante en terme de synchronisation serait la suivante (méthode utilisé dans plusieurs moteurs 3D)

    Les Threads qui effectuent le traitement mettent les résultats dans une pile... et en fait, ta pile sera une pile d'Array...

    Une fois que le thread achève son traitement, il empile le tableau de points sur la pile et lève un evenement pour le thread d'affichage.

    Celui ci, va récupérer les données de la pile, les affichés et il n'y aura aucun risque d'une écriture durant ce traitement puisque si un thread a de nouveaux points à fournir, il les empilera sur la pile... donc, pas de risque de collision

    Tu vois le truc ?

    The Monz, Toulouse
    The Monz, Toulouse
    Expertise dans la logistique et le développement pour
    plateforme .Net (Windows, Windows CE, Android)

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

Discussions similaires

  1. xsl:for-each avec un parametre pour select
    Par arnog dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 26/08/2008, 14h09
  2. fonction for each key .......
    Par trialrofr dans le forum ASP
    Réponses: 13
    Dernier message: 10/01/2005, 15h29
  3. apply-templates et for-each
    Par d'Oursse dans le forum XSL/XSLT/XPATH
    Réponses: 5
    Dernier message: 14/05/2004, 09h38
  4. utilisation de for each
    Par billoum dans le forum ASP
    Réponses: 5
    Dernier message: 19/03/2004, 16h30
  5. [VB6] For Each ... In ...
    Par Troopers dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 03/02/2003, 13h56

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