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 :

Déclencher un événement dans une méthode callback


Sujet :

C#

  1. #1
    Membre habitué
    Profil pro
    Développeur .Net, Administrateur système
    Inscrit en
    Octobre 2003
    Messages
    219
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur .Net, Administrateur système
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2003
    Messages : 219
    Points : 135
    Points
    135
    Par défaut Déclencher un événement dans une méthode callback
    Bonjour,


    j'ai un objet qui execute un long traitement de manière asynchrone. Pour le faire, j'ai utilisé un traitement asynchrone avec méthode de rappel (Callback) et jusque là pas de souci.

    Dans la méthode de fin de traitement, je déclenche un événement pour ramener l'objet issu du traitement.

    Cet objet est récupéré par le formulaire et par rapport à cet objet des mises à jour de labels sont effectuées.

    C'est sur ce dernier point que ça coince puisque j'ai une InvalidCrossThread Exception.

    Ma question est donc de savoir comment est il possible de déclencher un événement dans une méthode callback sans générer cette exception.


    Merci pour votre aide.


    note: L'exception n'est jetée qu'en mode debug. Je travaille sous VS2005.

    note: je n'ai pas envie de desactiver le controle d'operation interthread car il ne me semble pas que ce soit propre.

  2. #2
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Il faut que la méthode de la form qui récupère le résultat de ton thread asynchrone mette à jour les contrôles sur le thread de la form.

    Un truc de la forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class UneForm : Form
    {
      void f()
      {
        object obj = UneMethodedeLaMortAsynchrone();
        this.BeginInvoke(this.g, new object[] { obj });
      }
     
      void g(object trucMuche)
      {
       // ici, on est dans le thread de la form, car g a été appelée via le BeginInvoke de la form
       this.texbox1.Text = trucMuche.Bidule.Text;
      }
    }
    ಠ_ಠ

  3. #3
    Membre habitué
    Profil pro
    Développeur .Net, Administrateur système
    Inscrit en
    Octobre 2003
    Messages
    219
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur .Net, Administrateur système
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2003
    Messages : 219
    Points : 135
    Points
    135
    Par défaut
    Merci Guulh pour ta réponse rapide et efficace !

    J'ai testé et cela marche par contre, au risque d'être pointilleux, j'aurai vraiment aimé pouvoir utiliser cet objet qui exécute de longs traitements dans plusieurs forms sans avoir à passer par this.invoke dans la gestion de l'événement.

    Pourquoi ? Parce que c'est trompeur quelques part. Le développeur qui utilise cet objet qui effectue de long traitement s'attend à ce qu'il soit dans la thread principal sur l'événement FinTraitement.

    Qu'en penses tu ? Si tu as d'autres idées la dessus, merci d'avance !

  4. #4
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Il faut bien passer par un Invoke / BeginInvoke, puisque la fin d'un traitement sur un worker thread est sensé modifier les contrôles, qui eux ne peuvent être modifiés que dans le thread UI...

    Tu développes un composant ? La plupart des composants potentiellement asynchrone ont une propriété de type ISynchronizeInvoke, nommée par exemple SynchronizingObject.

    Ensuite, quand ton composant veut lever un événement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if (TonEvent != null)
                {
                    if (SynchronizingObject != null && SynchronizingObject.InvokeRequired)
                        SynchronizingObject.Invoke(TonEvent, new object[] { this, tonEventArgs });
                    else
                        TonEvent(this, tonEventArgs);
                }
    Dans la form qui contient le composant, un petit tonComposant.SynchroObejct = this et zou.
    ಠ_ಠ

  5. #5
    Membre habitué
    Profil pro
    Développeur .Net, Administrateur système
    Inscrit en
    Octobre 2003
    Messages
    219
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur .Net, Administrateur système
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2003
    Messages : 219
    Points : 135
    Points
    135
    Par défaut
    J'ai bien compris la solution que tu proposes. (Pas du premier coup lol)

    Ceci dit, connais tu AsyncOperation et AsyncOperationManager ?

    En créant une opération (objet de type AsyncOperation grace à AsyncOperationManager) et en utilisant la méthode post"FinTraitement" j'ai réussi à atteindre le résultat souhaité.

    En prime, j'ai pas besoin d'indiquer le formulaire dans le constructeur de mon objet qui exécute un long traitement.


    Merci pour ton aide !

    note: le tout étant de crée l'opération avant le traitement asynchrone (et non pendant)

  6. #6
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Ah tiens, je connaissais pas ! Merci aussi
    ಠ_ಠ

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

Discussions similaires

  1. Utiliser propriété de mon objet dans une méthode callback ?
    Par StringBuilder dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 19/11/2014, 10h08
  2. Comment proposer un callback dans une méthode ?
    Par student_php dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 08/07/2012, 16h45
  3. instanciation problématique dans une méthode ActiveX
    Par mr.saucisse dans le forum MFC
    Réponses: 14
    Dernier message: 17/01/2006, 16h34
  4. Réponses: 2
    Dernier message: 15/11/2004, 15h12
  5. Perte de gestionnaire d'événements dans une fenêtre
    Par Benjamin GAGNEUX dans le forum Composants VCL
    Réponses: 15
    Dernier message: 23/08/2004, 20h14

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