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 :

partager une list<string> entre 2 thread


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre extrêmement actif Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    2 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 2 037
    Par défaut partager une list<string> entre 2 thread
    Bonjour

    Je cherche a écouter un port UDP sur lequel je dois recevoir une trame périodiquement.
    Là je le fais en remplissant une list<String> ainsi
    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
            private  void UDPListener(int portEcoute)
            {
                Task.Run(async () =>
                {
                    IPEndPoint myIPendPoint = new IPEndPoint(IPAddress.Any, portEcoute);
     
                    using (var udpClient = new UdpClient(myIPendPoint))
                    {
                        string loggingEvent = "";
     
                        while (true)
                        {
                            var receivedResults = await udpClient.ReceiveAsync();
     
                            loggingEvent += Encoding.ASCII.GetString(receivedResults.Buffer);
     
                            mylist.Add(loggingEvent);
     
                            loggingEvent = "";
                        }
                    }
                });
            }
    le but étant de pouvoir afficher ce que j'ai reçu sur le thread de la form
    avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
                textBox1.Clear();
     
                foreach (var item in mylist)
                {
                    textBox1.AppendText(item + " \r\n");
                }
    que j'ai pour le moment mis sur un timer (ça clignote, c'est moche mais c'est pour apprendre...)

    tout ceci fonction jusqu'à un beau plantage System.InvalidOperationException
    La collection a été modifiée ; l'opération d'énumération peut ne pas s'exécuter

    forcément j'ai un thread qui rempli la list<string> et un autre qui cherche à faire une énumération.

    En c avec les OS temps réels je connais les mutex pour gérer ça mais là je n'arrive pas à trouver le nom de ce que j'ai besoin de mettre en place pour éviter le conflit.

    Merci par avance pour votre aide

  2. #2
    Membre Expert
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes
    Inscrit en
    Octobre 2008
    Messages
    1 966
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 966
    Billets dans le blog
    7
    Par défaut
    bonjour,

    Si tu souhaites modifier ta liste et etre notifié d'un ajout ou une supression à un instant T alors peut etre devrais tu utiliser une ObservableCollection.
    Regardes ce sujet, en espérant qu il puisse t inspirer :
    http://www.developpez.net/forums/d15...c/#post8671424

    a+

  3. #3
    Membre extrêmement actif Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    2 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 2 037
    Par défaut
    Outch

    Autant C# est redoutablement simple et puissant pour pleins de trucs, autant ça devient une usine à gaz pour gérer les échanges entre thread, entre forme et compagnie !
    allé je m'accroche, demain matin je saurai j'espère mettre en œuvre ces 553425233 déclarations pour avoir un évènement !

    et dire qu'un mutex ça se gère en 1 ligne...

    Merci

  4. #4
    Membre Expert
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Par défaut
    Remettons les choses à leur place : l'erreur que tu obtiens n'est pas (directement) liée aux thread ; elle te signifie juste que tu as modifié la collection sur laquelle tu itérais (que ce soit par un [autre] thread ou pas n'entre pas en ligne de compte). On aurait exactement la même erreur ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    static void Main (){
        var sample = new List<int> { 42 };
     
     
        foreach (var item in sample)
            sample.Add (666);
    }
    Donc déjà tu peux remplacer ton foreach par un for classique et voir si ça plante toujours (probablement pas) et si le comportement est bien celui escompté.

    Quant au mutex ; il y a pléthore d'option dans l'espace de nom System.Threading (les classes Mutex, Monitor, Semaphore ou ReaderWriterLock notamment) sans parler du mot clef lock

  5. #5
    Membre extrêmement actif Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    2 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 2 037
    Par défaut
    Merci pour la remise en place

    comme je suis en plein apprentissage je vais quand même me battre pour tenter de comprendre ces evenements. Je les manipules depuis des années via les propriétés des composants mais via le code ou mes propres classes j'ai jamais tenté plus qu'un orteil dans cette zone trouble.
    C'est quand m^me la grande classe de faire un truc quand il y a besoin plutôt que toutes les demi-secondes..

  6. #6
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 198
    Par défaut
    Citation Envoyé par petitours Voir le message
    Outch

    Autant C# est redoutablement simple et puissant pour pleins de trucs, autant ça devient une usine à gaz pour gérer les échanges entre thread, entre forme et compagnie !
    allé je m'accroche, demain matin je saurai j'espère mettre en œuvre ces 553425233 déclarations pour avoir un évènement !

    et dire qu'un mutex ça se gère en 1 ligne...

    Merci
    il n'y a rien de compliqué, c'est parce que tu ne sais pas que tu penses que c'est compliqué
    avec lock ca fait une ligne de code pour que chacun ne puisse pas faire leur truc en même temps
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  7. #7
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2016
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2016
    Messages : 64
    Par défaut
    Salut,

    comme dit plus haut ton erreur n'est pas (directement) liée au multithreading.
    Pour gérer les collections en multithread, tu as toutes les collections de l'espace de nom System.Collections.Concurrent.
    Pour ton problème précis, c'est parce que tu ne peux pas modifier un IEnumerable en même temps que tu utilises son énumérateur (qui est créé implicitement dans une boucle foreach).
    Plus haut quelqu'un a parlé d'ObservableCollection ; c'est bien pour notifier automagiquement les modifs d'une collection et les répercuter ailleurs, (ça implémente INotifyCollectionChanged, une sorte de pattern Observer pour les collections), c'est utilisé nativement par les contrôles type List etc. dans WPF par exemple). Mais dans ton cas ça ne marcherait pas, parce que l'ajout au contrôle visuel serait lancé par un thread différent de celui qui l'a créé et ça planterait.
    Pour résoudre très rapidement ton problème, tu peux par ex. utiliser lock. Tu lui spécifies une référence d'objet (en général un objet qui ne qu'à ça), et tant qu'un thread est à l'intérieur de l'instruction définie par le lock, les autres threads sont bloqués et doivent attendre pour eux-mêmes pouvoir mettre un lock dessus :
    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
     
    ....
    ....
    private readonly object synclock = new object();
    ....
    ...
     
    List<string> listCopy = null;
    lock (this.synclock)
    {
    listCopy = mylist.ToList();
    }
     foreach (var item in listCopy)
                {
                    textBox1.AppendText(item + " \r\n");
                }
    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    lock (this.synclock)
    {
    mylist.Add(loggingEvent);
    }

  8. #8
    Membre extrêmement actif Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    2 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 2 037
    Par défaut
    merci
    Je me rabats sur lock faute de réussir à gérer les évènements.
    mais je vais y revenir, là je lis ma liste toutes les 2secondesqu'il y ait eu changement ou pas, ce serait topissime de déclencher un événement quand il y a modification ; plus te taches inutiles et plus réactif.

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

Discussions similaires

  1. [ArrayList] contains() sur une liste de String
    Par nicotine002 dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 18/01/2008, 19h19
  2. affichage d'une list de String
    Par ganga dans le forum iReport
    Réponses: 1
    Dernier message: 27/11/2007, 10h01
  3. récupérer la partie commune d'une liste de String
    Par Kanter dans le forum Delphi
    Réponses: 11
    Dernier message: 18/04/2007, 12h46
  4. Réponses: 23
    Dernier message: 08/06/2006, 15h06
  5. Comparaison d'une liste de string à un string
    Par maxazac dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 19/10/2005, 15h39

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