Event ... Bonne ou mauvaise méthode ?

Signaler
Messages postés
514
Date d'inscription
mercredi 19 mars 2003
Statut
Membre
Dernière intervention
1 mars 2009
-
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
-
Bonjour,
Alors voilà ... Cette fois, ça y est, j'ai compris le mécanisme des events ... Alléluia comme dirait l'autre ... Bref. Du coup, je me retrouve avec une classe Server qui va posséder des evenements différents. Du coup, je suis obligé (je crois) de créer autant de classes que d'évenements différents ... Et du coup, est-ce qu'il est judicieux de placer l'ensemble des classes et des délégués comme internes à la classe ?
En gros, est-ce que ça, c'est bien (surtout la partie en rouge) ?



using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.IO;

namespace ConsoleApplication1
{
    class Server
    {
        public event ServerEventHandler OnMessage;
       
       
        // Client.
        TcpClient Client;
       
        // Port à écouter.
        private int Port;

        // TCPListener.
        private TcpListener Listener;

        // Thread du TCPListener.
        private Thread ListenerThread;

        // Constructeur.
        public Server(int port)
        {
            this.Port = port;
            this.ListenerThread = new Thread(this.Listen);
        }

        // Démarrage de l'écoute du serveur.
        public void Start()
        {
            this.ListenerThread.Start();

        }

        // Ecoute du serveur.
        private void Listen()
        {
            TcpClient client;
            IPEndPoint ip;
            this.Listener = new TcpListener(new IPEndPoint(IPAddress.Parse("127.0.0.1"), this.Port));
            this.Listener.Start();
            //this.Listener.
            client = this.Listener.AcceptTcpClient();
            this.Client = client;
            ip = (IPEndPoint)client.Client.RemoteEndPoint;
            //this.Send("Bienvenue " + ip + " !");
            //Console.WriteLine(Convert.ToString(client.Connected));
            this.Send("Salut à toi, " + ip.ToString() + " ... Soit le bienvenue. ");
            Thread receive_thread = new Thread(new ThreadStart(this.Receive));
            receive_thread.Start();
        }

        // Arrêt de l'écoute du serveur.
        public void Stop()
        {
            //this.ListenerThread;
        }

        // Envoie d'un message.
        public void Send(string text)
        {
            TcpClient client;
            Stream stream;
            BinaryWriter writer;
            client = this.Client;
            stream = client.GetStream();
            writer = new BinaryWriter(stream);
            writer.Write(text);
        }

        // Reçoit un message.
        public void Receive()
        {
            TcpClient client;
            Stream stream;
            BinaryReader reader;

            client = this.Client;
            stream = client.GetStream();
            reader = new BinaryReader(stream);
            string text;
           
            try
            {
                while (true)
                {
                    text = Convert.ToString(Convert.ToChar(reader.ReadByte()));
                    ServerEventArgs e;
                    e = new ServerEventArgs(text);
                    if (this.OnMessage != null) this.OnMessage(this, e);
                }
            }
            catch
            {

            }
            finally
            {
                this.Client.Close();
            }
        }
        internal class ServerEventArgs : EventArgs
        {
            private string _message;
            public string Message
            {
                get
                {
                    return _message;
                }
            }

            public ServerEventArgs(string message)
            {
                this._message = message;
            }
        }
        internal delegate void ServerEventHandler(object sender, ServerEventArgs e);
    }
}



Merci de vos conseils !
++ !
Localstone

7 réponses

Messages postés
794
Date d'inscription
vendredi 24 septembre 2004
Statut
Membre
Dernière intervention
19 août 2008
9
La réponse à la question m'interresse car je ne sais toujours pas non plus comment organiser ces classes (les "event args")...

Cela dis petite précision tu n'a pas forcément autant de classe / délégué que d'évènement, tu peux factoriser lorsque c'est possible :

Par exemple dans le Framework, les évènements Form.Load et Timer.Tick utilisent tous les deux un simple EventArgs. De la même façon, les évènement de souris utilisent généralement tous le même MouseEventArgs...
Messages postés
514
Date d'inscription
mercredi 19 mars 2003
Statut
Membre
Dernière intervention
1 mars 2009

Bah en fait, ici, par exemple, il y a l'evenement OnMessage qui permet d'obtenir le message, mais y aura aussi l'evenement OnNewConnexion qui permetera d'obtenir l'IP de la personne qui veut se connecter, etc. ... Je ne pense pas que l'on puisse factoriser dans ce cas là.
Maintenant, c'est clair que si l'évenement n'a rien à retourner ... Bah la factorisation est possible.
Localstone
Messages postés
794
Date d'inscription
vendredi 24 septembre 2004
Statut
Membre
Dernière intervention
19 août 2008
9
Effectivement tu ne peux pas tout factoriser... mais par exemple si tu as un evènement OnNewConnexion tu aura surement aussi un évènement OnConnexionLost, ou bien encore OnDisconnexion... et tu pourrais dans ce cas utiliser le même "event args", qui contiendrait par exemple l'ip concernée + l'état de la connexion. Dans ce cas ça à un sens, mais effectivement, le OnMessage est différent et aura sa propre classe d'argument...

Ca permet en tout cas de réduire un peu le nombre de ces classes, car ca grossit vite, et tout comme toi je ne sais jamais trop comment "ranger" tout ça... (par contre attention à ne pas vouloir trop factoriser en regroupant des choses qui n'ont rien a voir, car la on sacrifie la clareté du code pour réduire son "volume" et c'est généralement pas une bonne idée ;)
Messages postés
514
Date d'inscription
mercredi 19 mars 2003
Statut
Membre
Dernière intervention
1 mars 2009

Je note ! Merci de ton conseil !
Localstone
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
38
Salut,

Si ton évènement est public ta classe *EventArgs et ton delegué *EventHandler ne doivent pas être "nested", imbriqués, bien que soit possible mais en tout cas il doivent avoir le même niveau de visibilité que l'évènement car si l'évènement est accessible et pas son paramètre par exemple,il y a un problème..


Pour un bon exemple d'implémentation du modèle des évènements regard ce code de Coq, qui est parfait et respecte le modèle avec les méthodes protégées On*...



http://www.csharpfr.com/codes/IMESSAGEFILTER-EVENEMENTS-MOUSEMOVE-MOUSEENTER-MOUSELEAVE-NIVEAU-CONTROLE-SANS_35443.aspx


En .NET 2.0 on peut eviter de définir un EventHandler différent à chaque fois, grace au délégué générique EventHandler< TEventArgs >.
Messages postés
514
Date d'inscription
mercredi 19 mars 2003
Statut
Membre
Dernière intervention
1 mars 2009

Ok, je prends note de tout cela également. D'ailleurs, merci du "tuyau" pour EventHandler< TEventArgs >, ça rend le code plus propre et plus joli (je trouve ...) !
++ !
Localstone
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
87
Merci pour la référence ^^

/*
coq
MVP Visual C#
*/