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

  1. #1
    Membre actif
    [C#][2.0] Comment faire une gestion d'exception de manière globale ?
    Bonjour,

    je développe une application client/serveur. J'utilise .Net Remoting pour les échanges. Sur le serveur il y a une base de données et une application qui gère les échanges avec cette base de données

    Côté serveur j'ai donc des classes qui me permettent de gérer les clients, les commandes, etc.

    Code c# :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public class Serveur
    {
        public GestionClient gestionClient;
     
        public GestionCommande gestionCommande;
     
        [..]
    }


    Côté client, j'ai une classe appelé RemoteAccess.
    Cette classe présente les méthodes d'accès pour appelé les classes de gestion client, de gestion commandes:

    Code c# :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public class RemoteAccess
    {
         public GestionClient gestionClient;
     
         public GestionCommande gestionCommande;
     
         [..]
    }


    Dans le reste de mon application cliente, j'ai instancié la classe RemoteAccess et j'aimerais gérer de manière globale les exceptions pouvant survenir (SocketException, RemotingException.)

    Pour être plus clair, j'aimerai à chaque fois que je veux accéder à une méthode des classes GestionClient et GestionMethode ne pas devoir faire:

    Code c# :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    try
    {
        m_RemoteAccess.GestionClient.LoadClient();
    }
    catch (SocketException ex)
    {
    }
    catch (RemotingException ex)
    {
    }



    Code c# :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    try
    {
        m_RemoteAccess.GestionCommande.LoadCommande();
    }
    catch (SocketException ex)
    {
    }
    catch (RemotingException ex)
    {
    }


    mais pouvoir factoriser et attraper les exceptions à un seul endroit...
    Comment faire ?
    Merci de votre aide.

  2. #2
    Membre expérimenté
    Trois solutions :
    1 - Sous couche intermédiaire
    Tu peux 'encapsuler' tous les appels au remoting dans une 'couche intermédiaire' (et les mettre dans la classe qui te semble convenir le mieux, voir en créer une nouvelle), et y coller ta gestion d'exception.
    Ex : Si m_RemoteAccess.GestionClient.LoadClient() doit être appelé 5 fois, tu fais une méthode 'myRemotingManager.LoadClient' qui contient le seul et unique appel à la précédente méthode, entouré d'un unique try catch.
    (chui clair là ? bof..)

    2 - Super couche
    Tu entoures l'appel à Application.Run d'un try catch, qui fait que le plantage sera géré. Bon le seul problème c'est que ta Form sera morte

    3 - Gestion découplée
    Tu fais ton try/catch à chaque fois, mais tu catch uniquement Exception histoire que ça soit plus rapide à coder, et systématiquement, tu passes celle-ci à un méthode ManageException(Exception exc), qui elle va checker le type exact de l'exception et faire le message d'erreur approprié.


    Maintenant, si tu veux un message personnalisé en fonction de l'exception et de l'endroit où est appelé la méthode, alors pas le choix : faut tout faire à la main.

  3. #3
    Membre actif
    Bonsoir Mose,

    et merci pour la réponse.
    La solution 1 est très interessante mais ça signifie alors qu'il faut rappeler côté interface toutes les méthodes une à une pour les entourer d'un try/catch ?

    Hors j'aurais aimé pour toutes les méthodes de tous les membres de la classe RemoteAccess avoir un try/catch global. Ce serait la soluce idéale.

    Donc il resterait la solution 2 qui n'est apparemment pas envisageable.

    Bon bah il ne me reste plus qu'à partir vers la solution 1.

    Je me demande si je n'ai pas encore un problème d'architecture.

    Merci.

  4. #4
    Membre expérimenté
    Sinon tu peux utiliser la Programmation Orientée Aspect (POA) tu trouveras surement des exemples sur internet
    Mehdi Feki : Modérateur .Net

  5. #5
    Membre actif
    Bonjour,

    j'ai lu des documents sur la POA. Cela semble très interessant.
    Malgrès tout y aurait-il une autre solution que la POA ? Je pense à l'utilisation d'un proxy réel propriétaire.

    Merci d'avance pour vos idées.

    Merci d'avance.

  6. #6
    Rédacteur

    Salut .

    Une autre solution est de créer un délégué par type de fonction (qui renvoit un objet, qui renvoi un int et ainsi de suite ) que tu passes en parametre à une classe de gestion. L'avantage de ce système c'est que non seulement tu peux gérer les exceptions mais également les choses du genre Invoke cas tu as des threads et de l'accès à des compos graphique ...
    Par contre c'est assez lourd de coder tout les délégués necessaire
    - MVP C#
    -Tout problème a une solution, le vrai problème est de trouver la solution .....
    - Linux & mono : l'avenir

  7. #7
    Membre actif
    Bonjour,

    je te remercie pour ta réponse. Comme je le disais, ma gestion des exceptions a lieu dans le cadre de l'utilisation de .Net Remoting.
    Que penses-tu de définir un proxy réel propriétaire dont la méthode Invoke est redéfinie de la manière suivante:

    Code c# :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
    public override IMessage Invoke(IMessage msgIn)
            {
                // Place l'URI de l'objet distant dans MsgIn
                IDictionary d = msgIn.Properties;
                d["__Uri"] = m_URI;
     
                // Représente la méthode appelée
                IMethodCallMessage msgAppel = (IMethodCallMessage)msgIn;
     
                // Représente le message de retour
                IMethodReturnMessage msgOut = null;
     
                try
                {
                    log.DebugFormat("Avant appel de la méthode: {0}", msgAppel.MethodName);
     
                    // Appel synchrone du message
                    msgOut = (IMethodReturnMessage)m_MsgSink.SyncProcessMessage(msgIn);
     
                    log.DebugFormat("Après appel de la méthode: {0}", msgAppel.MethodName);
     
                    return msgOut;
                }
                catch (Exception ex)
                {
                    log.Error("Erreur d'accès distant.", ex);
                }
     
                return msgOut;
            }


    Merci d'avance.

  8. #8
    Rédacteur

    Citation Envoyé par Pilloutou

    Que penses-tu de définir un proxy réel propriétaire dont la méthode Invoke est redéfinie de la manière suivante:
    Que j'ai horreur de ce terme de Propriétaire .

    Plus sérieusement je ne parlais pas de la méthode invoke de Remoting mais des composants graphiques comme les forms, les textbox etc, etc, etc ...

    maintenant ta méthode à l'air très très interessante. Je vais me pencher dessus dès que j'ai un peu de temps
    - MVP C#
    -Tout problème a une solution, le vrai problème est de trouver la solution .....
    - Linux & mono : l'avenir