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 :

Problème de Event Handles


Sujet :

C#

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2006
    Messages : 19
    Points : 11
    Points
    11
    Par défaut Problème de Event Handles
    Salut à tous,

    J'essaie de me créer un petit chat et pour ce faire, j'essaie de détecter le changement de la valeur d'une liste (les messages).
    J'utilise un backgroundWorker pour l'attente d'un nouveau message. Lorsqu'un nouveau message est envoyé, le backgroundWorker ajoute ce nouveau message à la variable liste. Celle-ci est donc modifiée et doit donc, à ce moment là incrèmenter une listeBox.
    J'espère avoir été assez compréensible pour l'instant.

    Mon problème est le suivant: tout se déroule bien mise à part que je n'arrive pas à atteindre la listBox pour l'incrémenter.
    Pare contre j'arrive à lister les message à l'aide d'un MessaBox.Show().

    Voici le code en espérant que vous pourez proposer des solutions
    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Net.Sockets;
    using System.Net;
     
    namespace WindowsFormsApplication1
    {
        using MyCollections;
     
        public partial class Form1 : Form
        {
            private UdpClient udp;
            private ListWithChangedEvent messages = new ListWithChangedEvent();
     
            public Form1()
            {
                InitializeComponent();
                udp = new UdpClient(1600);
                EventListener listener = new EventListener(messages);
                backgroundEcouteMessage.RunWorkerAsync();
            }
     
            private void backgroundEcouteMessage_DoWork(object sender, DoWorkEventArgs e)
            {
                try
                {
                    IPEndPoint EmetteurIpEndPoint = new IPEndPoint(IPAddress.Any, 1600);
                    Byte[] donneesRecues = udp.Receive(ref EmetteurIpEndPoint);
                    string message = Encoding.Unicode.GetString(donneesRecues);
                    string ip = EmetteurIpEndPoint.Address.ToString();
                    messages.Add("message de " + ip + " : " + message);
                }
                catch { }
            }
     
            private void backgroundEcouteMessage_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                backgroundEcouteMessage.RunWorkerAsync();
            }
        }
     
        public class EventListener
        {
            private ListWithChangedEvent Messages;
     
            public EventListener(ListWithChangedEvent list)
            {
                Messages = list;
                Messages.Changed += new ChangedEventHandler(ListChanged);
            }
     
            private void ListChanged(object sender, EventArgs e)
            {
                foreach (string mes in Messages)
                {
                    MessageBox.Show(mes);
                    //lstMessages.Items.Add(mes);
                }
            }
     
            public void Detach()
            {
                Messages.Changed -= new ChangedEventHandler(ListChanged);
                Messages = null;
            }
        }
    }
    Et le "MyCollections"
    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    namespace MyCollections
    {
        using System;
        using System.Collections;
     
        public delegate void ChangedEventHandler(object sender, EventArgs e);
     
        public class ListWithChangedEvent : ArrayList
        {
            public event ChangedEventHandler Changed;
     
            protected virtual void OnChanged(EventArgs e)
            {
                if (Changed != null)
                    Changed(this, e);
            }
     
            public override int Add(object value)
            {
                int i = base.Add(value);
                OnChanged(EventArgs.Empty);
                return i;
            }
     
            public override void Clear()
            {
                base.Clear();
                OnChanged(EventArgs.Empty);
            }
     
            public override object this[int index]
            {
                set
                {
                    base[index] = value;
                    OnChanged(EventArgs.Empty);
                }
            }
        }
    }
    Merci d'avance pour votre aide qui, je l'espère me sera très précieuse

  2. #2
    Membre expert
    Avatar de GuruuMeditation
    Homme Profil pro
    .Net Architect
    Inscrit en
    Octobre 2010
    Messages
    1 705
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Belgique

    Informations professionnelles :
    Activité : .Net Architect
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2010
    Messages : 1 705
    Points : 3 568
    Points
    3 568
    Par défaut
    Tu es en Winform, ou à base de XAML ?

    Si c'est du XAML, tu peux utiliser une observablecollection, par exemple, et faire du databinding dessus.
    Microsoft MVP : Windows Platform

    MCPD - Windows Phone Developer
    MCPD - Windows Developer 4

    http://www.guruumeditation.net

    “If debugging is the process of removing bugs, then programming must be the process of putting them in.”
    (Edsger W. Dijkstra)

  3. #3
    Membre éprouvé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2011
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2011
    Messages : 487
    Points : 945
    Points
    945
    Par défaut
    Au vu du namespace:

    namespace WindowsFormsApplication1
    {
    Je pense que c'est du WinForm.


    Par curiosité, pourquoi hérites tu d'ArrayList et pas de List<T> ? Au vu du reste du code, j'imagine que c'est parce que tu viens du Java. Je n'ai pas l'habitude de voir une classe comme ton EventListener en C#.

    Je pense que ton soucis est que tu as "externalisé" la gestion de ton "CollectionChanged" dans une autre classe, alors que ça pourrait être fait directement dans ta première classe en t'abonnant avec +=.
    Mon blog sur les technos .NET et Agile -> http://blog.developpez.com/maximepalmisano/

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2006
    Messages : 19
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par MaximePalmisano Voir le message
    Au vu du namespace:



    Je pense que c'est du WinForm.


    Par curiosité, pourquoi hérites tu d'ArrayList et pas de List<T> ? Au vu du reste du code, j'imagine que c'est parce que tu viens du Java. Je n'ai pas l'habitude de voir une classe comme ton EventListener en C#.

    Je pense que ton soucis est que tu as "externalisé" la gestion de ton "CollectionChanged" dans une autre classe, alors que ça pourrait être fait directement dans ta première classe en t'abonnant avec +=.
    Tout d'abord merci pour vos réponses.
    Pour ce qui est de ta curiosité, je ne connais juste pas la solution dont tu me parle en citant List<T> car je ne la connais pas. parles-tu d'un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    List<String> MaListe = new List<String>()
    ?

    Si oui, effectivement j'aurais pu.
    Cela dit, je doute que mon problème vienne de là.
    J'ai modifié le code et n'appelle plus ma classe EventListening. Je m'abonne dirrectement via Form1() ma classe de base.
    Cela me donne une classe inutile de moin.

    Pour ce qui est de mon problème, lors de la réception d'un message, la fonction RefreshMessages() s'exécute bien mais n'arrive pas à incrémenter le textBox que j'ai créé pour le test.
    Je dirrais même plus.
    Si je mets un "MessageBox.Show(mes)" à la place, du "txtMessage.Text += mes", cela affiche bien, les messages recus l'un après l'autre.
    Si je mets les deux, un seul MessageBox() apparet. Comme si la tentative d'accès à la textBox faisait planter la boucle ou fonction.

    PS: Aucune alerte en débug mod

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    namespace WindowsFormsApplication1
    {
        using MyCollections;
     
        public partial class Form1 : Form
        {
            private UdpClient udp;
            private ListWithChangedEvent messages = new ListWithChangedEvent();
     
            public Form1()
            {
                InitializeComponent();
                udp = new UdpClient(1600);
                messages.Changed += new ChangedEventHandler(ListChanged);
                backgroundEcouteMessage.RunWorkerAsync();
            }
     
            private void ListChanged(object sender, EventArgs e)
            {
                RefreshMessages();
            }
     
            private void RefreshMessages()
            {
                foreach (string mes in messages)
                {
                    //this.lstMessages.Items.Add(mes);
                    MessageBox.Show(mes);
                    this.txtMessages.Text += mes;
                }
            }
     
            public void Detach()
            {
                messages.Changed -= new ChangedEventHandler(ListChanged);
                messages = null;
            }
     
            private void backgroundEcouteMessage_DoWork(object sender, DoWorkEventArgs e)
            {
                try
                {
                    IPEndPoint EmetteurIpEndPoint = new IPEndPoint(IPAddress.Any, 1600);
                    Byte[] donneesRecues = udp.Receive(ref EmetteurIpEndPoint);
                    string message = Encoding.Unicode.GetString(donneesRecues);
                    string ip = EmetteurIpEndPoint.Address.ToString();
                    messages.Add("message de " + ip + " : " + message);
                }
                catch { }
            }
     
            private void backgroundEcouteMessage_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                backgroundEcouteMessage.RunWorkerAsync();
            }
        }
    }
    encore merci d'avance

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 93
    Points : 169
    Points
    169
    Par défaut
    Le problème c'est que t'essayes d'accéder à un élément graphique (this.txtMessages) depuis le thread d'exécution du background worker, ce qui n'est pas possible.
    D'ailleurs, si tu enlevais ton catch{} pas beau du tout dans backgroundEcouteMessage_DoWork tu verrais l'exception remontée

    Une des solutions est de mettre la propriété WorkerReportsProgress à True, et de binder l'événement ProgressChanged sur un handler qui appellera ta méthode d'affichage.
    Ce qui nous donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    private void ListChanged(object sender, EventArgs e)
    {
           backgroundEcouteMessage.ReportProgress(0);
           //RefreshMessages();
    }
     
     
    private void backgroundEcouteMessage_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
           RefreshMessages();
    }

  6. #6
    Membre éprouvé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2011
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2011
    Messages : 487
    Points : 945
    Points
    945
    Par défaut
    La remarque sur la List, c'était juste en passant, et oui je parlais bien de List<string> (<T> est le nom utilisé pour les génériques). Le truc c'est qu'ArrayList n'est pas typé donc List<T> est avantageux de ce côté.


    Dans ce genre de cas, je te conseille d'aller dans l'onglet Debug->Exceptions et de cocher la case thrown pour les Exceptions CLR.

    Ca te permettra d'avoir une "alerte" quand une exception est lancée, même si tu la catch. Du coup, tu peux avoir une idée des évènements qui te sont "cachés" par les catch.

    Jaco67 t'a donné la raison, on ne peut modifier l'UI que depuis le thread graphique. Comme tu es appelé dans une callback, tu n'es plus dans le même thread et ça pète.
    Mon blog sur les technos .NET et Agile -> http://blog.developpez.com/maximepalmisano/

Discussions similaires

  1. problème d'event sous X11/Motif
    Par awalter1 dans le forum Linux
    Réponses: 7
    Dernier message: 08/07/2008, 18h44
  2. [JTable] problème sélection / event
    Par Méta dans le forum Composants
    Réponses: 10
    Dernier message: 26/09/2007, 22h08
  3. Problème avec un handles
    Par cococococococo dans le forum Interfaces Graphiques
    Réponses: 6
    Dernier message: 26/06/2007, 13h12
  4. AWT et Event Handling
    Par henry.schmitt dans le forum AWT/Swing
    Réponses: 6
    Dernier message: 13/02/2006, 16h07
  5. Problème avec event handler
    Par MASSAKA dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 15/11/2005, 09h31

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