Delegate - je ne m'en sors pas

Résolu
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 - 10 juil. 2013 à 20:30
 Utilisateur anonyme - 11 juil. 2013 à 02:16
Salut ta tou(te)s

Voilà le topo :
J'ai une application de type "serveur COM" faite en VB6.
Je développe (VS 2012) une appli "client" qui se connecte à mon serveur COM.

A un moment donné, mon serveur envoie un RecordSet avec des données que l'interface client doit afficher dans un TreeView placé sur ma forme.
J'ai donc :
- Dans la partie déclarative de ma forme :
    Public WithEvents oServer As TCR_Server.Client
qui me permet de déclarer un objet connectable et évènementiel.
- L'évènement se produit bien et me fournit bien mon RecordSet
    Private Sub oServer_AreasList(ByRef rs As ADODB.Recordset) Handles oServer.AreasList
mais le problème se pose dès que j'essaye de peupler mon TreeView :

Je commence par faire un tvAreas.Nodes.Clear()
Tout se passe bien (de toute façon, il est encore vide à ce moment là)
Mais dès que je tente de créer le noeud principal
    tvAreas.Nodes.Add(New TreeNode("Root", 1, 1))
il m'insulte avec ce message :
Erreur n° 5 : "Action being performed on this control is being called from the wrong thread. Marshal to the correct thread using Control.Invoke or Control.BeginInvoke to perform this action."

Ouverture de l'aide, lecture ... de ce que j'arrive à comprendre.
Bon. Les infos provenant d'un évènement déclenché par mon appli serveur, il doit y avoir un mécanisme qui m'interdit de toucher aux objets de mon appli client.
Pourquoi pas (Ai-je bien compris ?).

Alors, dans l'aide, ils disent qu'il faut utiliser .Invoke ou .BeginInvoke.
J'ai donc déplacé mes instructions d'insertion des données dans une autre Sub (en Public) et j'envisage de lancer cette Sub avec la méthode Invoke.
Là commence les problèmes :

- .BeginInvoke
Premier problème : La syntaxe suggérée est
    tvAreas.BeginInvoke(New InvokeDelegate(AddressOf maNouvelleSub(monRecordSet)))
Hélas, le mot clé InvokeDelegate ne semble pas reconnu.
Mon appli n'utilise que le Framework 2 : Est-ce la raison ?
(je ne peux pas utiliser de version plus récente, cette appli étant destinée à des machines industrielles qui ont toujours un train de retard)
D'après l'aide, cela devrait fonctionner depuis la version 1.0
Mystère ...

- .Invoke
Leur exemple est (à mes yeux) trop complexe pour comprendre quoi mettre dans cette syntaxe.

Quelques conseils avertis me seraient bien utiles ...

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on le partage (Socrate)

4 réponses

Utilisateur anonyme
10 juil. 2013 à 21:37
Salut,

Comme le précise NHenry, et pour illustrer sa remarque, ça donnerait un truc du genre :
private delegate sub TonDelegue(rs as ADODB.Recordset)
'....

Private Sub oServer_AreasList(ByRef rs As ADODB.Recordset) Handles oServer.AreasList
   if tvAreas.invokeRequired then
       tvAreas.Invoke(new TonDelegue(addressof oServer_AreasList), rs)
   else
       'on peux lire les propriétés de rs ici
       tvAreas.Nodes.Add(New TreeNode("Root", 1, 1))
   end if
end sub
3
NHenry Messages postés 15112 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 13 avril 2024 159
10 juil. 2013 à 21:11
Bonjour,

Il faut que tu déclare un Delegate correspondant au prototype de ta fonction/sub, puis instancier celui-ci à la place de InvokeDelegate (si je ne me tromre pas).

v----Signature--------v----------------------------------------------
[list=ordered][*]Pour poser correctement une question et optimiser vos chances d'obtenir des réponses, pensez à lire le règlement CS, celui-ci pour bien poser votre question ou encore celui-ci pour les PFE et autres exercices.[*]Quand vous postez un code, merci d'utiliser la coloration syntaxique (3ième icône en partant de la droite : ).[*]En VB.NET pensez à activer Option Explicit et Option Strict (propriété du projet) et à retirer l'import automatique de l'espace de nom Microsoft.VisualBasic (onglet Références dans les propriétés du projet).[*]Si votre problème est résolu (et uniquement si c'est le cas), pensez à mettre "Réponse acceptée" sur le ou les messages qui vous ont aidés/list
---
Mon site
0
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
11 juil. 2013 à 01:48
Salut Nicolas et Laurent.
Merci pour votre appui

Si j'ai bien compris, quand il faut déléguer, on relance une seconde fois la fonction (ou on renvoie à une autre). C'est bien comme ça que cela marche ?

Mise en pratique avec l'illustration de Laurent : peu concluante.
J'ai déclaré mon délégué
    Public Delegate Sub oServer_AreaList_Dlgte(ByRef rs As ADODB.Recordset)

J'ai appliqué le test
        If tvAreas.InvokeRequired Then
            tvAreas.Invoke(New oServer_AreaList_Dlgte(AddressOf oServer_AreasList), rs)
        Else
mais blocage dès que le Invoke est exécuté.
Le programme est figé, sablier sur la forme, et je ne sais pas ce qu'il attend.

J'ai essayé de transférer, euh ... de déléguer vers une nouvelle Sub qui a les mêmes arguments (le rs). Pareil.
J'ai mis des Public partout (Sub et Delegate), sans succès.

Ah, j'allais poster cette réponse et un dernier test fournit plus d'espoir :
J'ai utilisé .BeginInvoke au lieu de .Invoke et cela semble fonctionner correctement !
Ouf

Merci à vous deux pour le coup de mains.

... voilà que je découvre qu'ils ont supprimé le Key dans les Nodes ... grr : encore quelques heures à chercher ses petits; ah la la VB.Net ...
0
Utilisateur anonyme
11 juil. 2013 à 02:16
Bonjour,

Si jamais les deux compères ne reviennent pas ce soir (du moins chez-moi). Je n'y comprend pas grand chose moi non plus, mais voilà une sorte de tutoriel étape par étapes (en anglais).

J'ai bien essayé de mettre delegates vb en pâture à leur moteur de recherche et il retourne un peu moins de 300 liens. Je me suis découragé après avoir lu 2 pages de résultats, tellement les réponses sont disparates. C'est le lien ci-haut qui m'a semblé le plus utile. Croisons les doigts.
0
Rejoignez-nous