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

VB.NET Discussion :

Invoke Delegate - plus souple


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé Avatar de megamario
    Homme Profil pro
    VB6/VB.net/C/C++/C#
    Inscrit en
    Septembre 2008
    Messages
    931
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : VB6/VB.net/C/C++/C#
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2008
    Messages : 931
    Par défaut Invoke Delegate - plus souple
    Bonjour à tous,


    J'aimerais savoir s'il y a un moyen de crée une méthode plus générique pour changer un objet graphique depuis un autre thread.

    Actuellement je crée une méthode par objet à modifier, par exemple pour changer un label:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Private Delegate Sub Changetext(ByVal txt As String)
     
    Public Sub ChangeLabel(ByVal txt As String)
            If Me.InvokeRequired Then
                Me.Invoke(New Changetext(AddressOf ChangeLabel), txt)
            Else
                lblMonLabel.Text =  txt
            End If
        End Sub
    Du coup cela peux me faire par mal de méthode qui se ressemble pour chaque objet a modifier.

    Je pensais à quelque chose comme récupérer dans l'autre thread les caractéristique de l'objet, le modifier puis le renvoyer, mais je vois pas trop comment faire.

    Merci de votre aide

  2. #2
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    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 197
    Par défaut
    ca peut se condenser de plusieurs manières
    sur vs 2010 depuis la méthode qui exécutée depuis un autre thread ca donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    lblMonLabel.invoke(new action() sub() lblMonLabel.Text =  "valeur")
    ca permet donc de manipuler les variables en cours d'utilisation


    sub permet de créer une sub anonymes, on peut aussi faire des sub de plusieurs lignes de la sorte

    avant vs 2010 on peut faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    .invoke(new action(of string)(addressof laméthode), "valeur")
     
    private sub laméthode (txt as string)
      lelabel.text = txt
    end sub
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre éprouvé Avatar de megamario
    Homme Profil pro
    VB6/VB.net/C/C++/C#
    Inscrit en
    Septembre 2008
    Messages
    931
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : VB6/VB.net/C/C++/C#
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2008
    Messages : 931
    Par défaut
    Merci pour l'info.

    Toutefois je vois pas trop comment la mettre en oeuvre.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    lblMonLabel.invoke(new action() sub() lblMonLabel.Text =  "valeur")
    Apparemment vous me dites que cela s’exécute a partir de mon autre thread. Mais mon autre thread ne connait pas "lblMonLabel"


    Sa serait éventuellement (j'ai pas testé):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    frmMain.lblMonLabel.invoke(new action() sub() lblMonLabel.Text =  "valeur")
    ou frmMain serait déclaré dans un module:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public frmMain as formMain
    J'ai pas testé pour le moment mais j'essaie de comprendre.

  4. #4
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    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 197
    Par défaut
    Citation Envoyé par megamario Voir le message
    Mais mon autre thread ne connait pas "lblMonLabel"
    si tu veux dire par là que le label est sur un autre thread, certes, mais ca ne limite en rien
    une variable n'est pas visible que depuis un thread mais depuis tous, c'est juste une question de portée après
    ce qui est autre chose que le fait qu'un controle ne soit pas modifiable depuis un autre thread ; il reste accessible

    si tu veux dire par là que depuis la sub qui est threadée tu n'as pas accès la lblMonLabel alors le code que nous as donné en exemple n'as aucune raison de fonctionner non plus ...


    si le code de ton thread est au même endroit que le code behind du form, il n'y a pas de soucis

    si le code ton thread est dans une autre classe il faut que cette classe connaisse le form ou le label (donc lui passer une référence, par exemple à la création)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Membre éprouvé Avatar de megamario
    Homme Profil pro
    VB6/VB.net/C/C++/C#
    Inscrit en
    Septembre 2008
    Messages
    931
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : VB6/VB.net/C/C++/C#
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2008
    Messages : 931
    Par défaut
    Citation Envoyé par Pol63 Voir le message
    si tu veux dire par là que le label est sur un autre thread, certes, mais ca ne limite en rien
    une variable n'est pas visible que depuis un thread mais depuis tous, c'est juste une question de portée après
    ce qui est autre chose que le fait qu'un controle ne soit pas modifiable depuis un autre thread ; il reste accessible

    si tu veux dire par là que depuis la sub qui est threadée tu n'as pas accès la lblMonLabel alors le code que nous as donné en exemple n'as aucune raison de fonctionner non plus ...


    si le code de ton thread est au même endroit que le code behind du form, il n'y a pas de soucis

    si le code ton thread est dans une autre classe il faut que cette classe connaisse le form ou le label (donc lui passer une référence, par exemple à la création)
    Merci déjà de t’intéresser a mon petit souci.


    Explication :

    En fait j'essaie de tout séparer, dans la form il n'y a que ce qu'il y a dans la form, donc gestion des évènement du à l'interface IHM, éventuellement des timers.

    Ensuite j'ai des classes ou l'algo de fonctionnement se retrouve.

    L'une d'entre elle me sert de communication avec le port COM. La boucle qui tourne pour lire le port COM est lancé par un autre thread.
    Donc tout ce qui découle de la lecture de mon Port COM se retrouve dans ce thread.
    L’analyse des trames par exemple. Dans l'une des trames se trouve la vitesse de COM final, car je dois la changer pour le client final, suivant sont application.

    Lorsque je trouve cette trame je la décortique et j'envoie l'information sur mon formulaire, le label, pour indiquer la vitesse de COM final entre autre car du coup je change aussi ma vitesse de COM.


    C'est une explication de l'une de mes applications en cours. Mais j'ai d'autre thread (pour telnet par exemple) etc...

    Plusieurs données à transmettre d'un thread à un autre pour l'affichage dans le formulaire.


    En ce qui concerne mon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Private Delegate Sub Changetext(ByVal txt As String)
     
    Public Sub ChangeLabel(ByVal txt As String)
            If Me.InvokeRequired Then
                Me.Invoke(New Changetext(AddressOf ChangeLabel), txt)
            Else
                lblMonLabel.Text =  txt
            End If
        End Sub
    Sa il se trouve dans le formulaire appelé : formMain

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    j'ai dans module
     
    public frmMain as formMain
     
    sub Main()
        frmMain = new formMain
        frmMain.showdialogue()  'Je l'écrit de tête
    end sub
    Depuis mon thread je fait (en simplifiant):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    frmMain.ChangeLabel("Nouveau baudrate = 115200")
    et sa cela fonctionne bien.
    Lorsque le thread appel la fonction il passe par le:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      If Me.InvokeRequired Then
                Me.Invoke(New Changetext(AddressOf ChangeLabel), txt)
    Puis sort et l'appli lance bien cette même fonction (lorsqu'elle est libre si j'ai bien compris) et modifie mon label.

  6. #6
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    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 197
    Par défaut
    Citation Envoyé par megamario Voir le message
    En fait j'essaie de tout séparer, dans la form il n'y a que ce qu'il y a dans la form, donc gestion des évènement du à l'interface IHM, éventuellement des timers.
    ca c'est un bon point

    Citation Envoyé par megamario Voir le message
    Lorsque je trouve cette trame je la décortique et j'envoie l'information sur mon formulaire, le label, pour indiquer la vitesse de COM final entre autre car du coup je change aussi ma vitesse de COM.
    ca c'est moins bien
    une classe de traitement ne doit pas dialoguer avec un form, il faut une classe de données intermédiaire
    j'y reviens plus bas

    Citation Envoyé par megamario Voir le message
    j'ai dans module
    public frmMain as formMain
    (...)
    Depuis mon thread je fait (en simplifiant):
    frmMain.ChangeLabel("Nouveau baudrate = 115200")
    donc dans ce cas tu vois comment adapter ce que je t'ai dis
    si tu fais frmMain.ChangeLabel, tu dois pouvoir faire frmMain.Invoke (...) frmMain.lbl.text = "valeur

    Citation Envoyé par megamario Voir le message
    (lorsqu'elle est libre si j'ai bien compris)
    en fait tout ce que doit faire le thread principal est mis sur une pile, quand la pile n'est pas vide chaque élément est traité chacun son tour
    cliquer sur un bouton met les subs liés à cet évènement sur la pile
    faire invoke met aussi sur la pile donc c'est bien quand le thread est dispo qu'il le fera (enfin souvent c'est quelques nanosecondes)


    donc je disais qu'il faut une classe intermédiaire

    si ton thread va lire une info sur le port com, il faut que ton thread stocke cette info dans une propriété
    et dans ton interface tu n'as qu'à lire cette propriété

    si ton port com te sers à lire plusieuers infos relatives à une même chose tu fais une classe [meme chose] avec en propriétés les différentes infos

    et du coup ca simplifie le travail, si la ou les instances de données sont sur un module, le thread peut écrire dedans, et l'interface peut lire dedans
    là ou c'est plus simple c'est que tu peux rendre ca asynchrone si ca ne pose pas de problèmes sur le traitement
    à savoir un timer sur le form qui toutes les x millisecondes va faire labelmachin.text = instance.propriété
    le timer étant exécuté sur le thread principal il n'y a pas besoin de délégué
    le thread lui a le droit de modifier une propriété qui n'est pas sur un control directement aussi

    attention, pour les collections, si un thread fait un for each pendant qu'un autre fait .add ca plante, il y a alors besoin de mettre des mécanismes de verrouillages
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

Discussions similaires

  1. Réponses: 5
    Dernier message: 01/12/2010, 10h03
  2. [WD-2003] Formulaire : comment rendre la mise en page plus souple ?
    Par Lucie_ dans le forum Word
    Réponses: 3
    Dernier message: 16/11/2010, 17h02
  3. Conversion Invoke Delegate C# en VB.net
    Par megamario dans le forum Visual Studio
    Réponses: 0
    Dernier message: 08/04/2010, 10h47
  4. [C#][Thread][Invoke] petit problème de delegate
    Par clinic dans le forum Général Dotnet
    Réponses: 3
    Dernier message: 22/06/2007, 11h38
  5. [P/Invoke/Delegates] Finesse d'un wrapper P/Invoke
    Par DeusXL dans le forum C++/CLI
    Réponses: 3
    Dernier message: 12/09/2006, 12h48

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