Problème de thread avec les sockets en .NET

Problème de thread avec les sockets en .NET - C#/.NET managed - Programmation

Marsh Posté le 28-03-2007 à 18:14:35    

Coucou tout le monde ===>> je requiert votre aide !
 
 
Voilà, je fais une appli réseau, c'est professionnel donc je n'en dévoilerai pas trop, mais bien suffisament !
Je travaille en VB.NET car c'est flexible et c'est rapide à développer (les utilisateurs finaux changent tout le temps d'avis sur tout ! Ha bon c'est normal ??  :sweat: )
 
 
Je vous demande de l'aide et des conseils car soit je rate une sacrée marche, soit les sockets sont super mal gérés. Perso je pense que j'ai dû rater une sacrée marche !
 
 
 
EXPLICATIONS GLOBALES
 
A la base de tout, il y a une appli serveur, et plusieurs appli clientes toutes différentes en terme de fonctionnalité, mais bien évidement identique dans le squelette réseau et qui se connecte toute à la même appli serveur.
 
 
J'ai donc sur mon serveur un socket en écoute.
Je peux avoir plusieurs utilisateurs de type ClientA connectés en même temps, plusieurs de type ClientB en même temps etc...
Pour savoir quoi répondre à chaque type de d'appli clientes (A, B C, etc), j'ai créé sur le serveur une class par type d'applis clientes :
ClassClientA
ClassClientB
ClassClientC
--avec chacune un contenu différent !
 
Quand un connexion se présente, le serveur créé un socket client auquel il raccorde la demande, détermine via un court dialogue avec l'appli de quelle appli il s'agit, puis en fonction charge une class adaptée, refile le socket client à cette class, et ajoute cette class dans une collection pour qu'elle reste instanciée ; elle sera automatiquement détruite quand les sockets clients en relation seront déconnectés. La class vit et fait son boulot en répondant à l'appli client avec laquelle elle a été connecté.
 
Côté client, pour faire simple, j'ai créé une class que j'ai appelé ClassComm (comme communication) et c'est elle qui est chargée de communiquer, elle contient le socket, reçoit les données, découpe les ordres et les messages reçu pour bien les traiter etc... cette ClassComm est présentes dans toutes mes applis clientes. La ClassComm reçoit les ordres du serveur, et dès qu'elle a un ordre complet, elle l'envoi "se faire traiter" dans l'appli cliente, qui réagit en fonction.
L'appli client n'est qu'une "interface", et je ne voulais pas que le code qui traite les ordres venant du réseau y figure, histoire de dissocier proprement.
 
Donc la côté client la classcomm reçoit, quand elle a bien découpé un ordre, elle le passe au traitement, qui lui agit sur l'interface.
 
 
[Serveur].ClassClient_TypeA..ClassComm <----- réseau LAN/WAN -----> ClassComm..Module_traitement > agit sur > [Appli Cliente A]
 
 
 
 
BREF tout ça fonctionne bien.
Mon problème arrive ci-dessous :
Les sockets en .NET ne sont pas évenementiels.
Alors pour bien les implémenter proprement, il faut mettre en oeuvre les begin receive / end receive avec les callbacks et compagnie. Là non plus pas de problème (sinon l'appli freeze à chaque fois qu'on attend des données...).
 
Sauf que dans le CallBack du receive, je reçoit mes données, je les ajoute à mon tampon de données reçus et j'y lance la routine de traitement du tampon pour trouver, découper et isoler les ordres qui y sont contenu. Et une fois les ordres prêt, je les transfère à mon module de traitement et celui-ci va aller influer sur les contrôles contenus dans mes forms de l'interface. Et là ça coince grave !
 
Parce qu'apparement le callback se fait dans un thread à part. Putain. Pardon. C'est nul non ? Moi je pensais que le callback REVENAIT dans le thread actuel, pour agir justement. Ben visiblement non. Et comme tout mon tointoin part depuis le callback (découpage, traitement, action) ben ça ne va pas !
 
Alors je me suis dit << pas grave >>, au callback receive j'ajoute juste dans le tampon, et le traitement tampon je le ferais depuis ailleurs : j'ai donc implémenté un timers.timer et j'ai mis que si le tampon n'est pas vide alors traitement tampon, toutes les 10 ou 100 ms.
Ben ça me fait pareil ! Ca veut dire que l'event elapsed du timers.timer est aussi threadé à part ????  :??:  
 
 
 
Franchement, les gurus, c'est moi qui merde dans l'implémentation des sockets non ? Alors où s'il vous plait ?  :jap:  
 
Parceque si on peut pas simplement agir sur une form depuis une class qui implémente un socket, où va le DOTNET ??!!  :sweat:  
 
 
 
Merci de m'avoir lu jusqu'ici !!!  :hello:

Reply

Marsh Posté le 28-03-2007 à 18:14:35   

Reply

Marsh Posté le 29-03-2007 à 10:30:05    

Up

Reply

Marsh Posté le 29-03-2007 à 11:56:02    

En gros, tu veut faire de la mise à jour de controles graphiques dans des opérations inter-thread ?
 
Si c'est bien cela.. => Invoke
 
Comme je suis faineant et que je hais au plus haut point le VB je te donne 2 solutions qui fonctionnent mais ne C# :D
 
http://blogs.msdn.com/csharpfaq/ar [...] 91685.aspx
 
ou sinon, en .NET 2, voici une méthode plus mignone :p
 
[ton controle].Invoke(new MethodInvoker(delegate()
{
    // Ici je fait mumuse avec mes controles graphiques
}));


Message édité par Koyomi le 29-03-2007 à 11:56:19
Reply

Marsh Posté le 29-03-2007 à 11:56:46    

EDIT : Koyomi, on a visiblement posté en même temps !!!
A l'heure ou j'ai rédigé mon message je n'avais pas de réponse !
Merci pour ton aide je vais aussi explorer cette voie, car je pense que ta solution est plus propre !!!
 
MERCI A TOI

_____________________________________________________________
 
 
Si toutefois le problème avait intéressé ou bien interressera quelqu'un à l'avenir, voici la << solution >>.
 
En fait tout parait bien normal, ce sont les inconvénients normaux liés aux threads. La solution que j'ai trouvé dans mon cas précis a été de laissé les callback nourrir le tampon dans leur monde à part (thread), et de mettre en place à nouveaux un fameux timers.timer sur lequel l'évènemenet Elapsed va explorer le tampon MAIS CETTE FOIS j'ai utilisé la propriété SynchronizingObject de mon timer, à laquelle j'ai donc affecté la feuille principale initiale de mon appli, afin que le traitement qui s'opère dans l'évènement du timer soit dans le << même monde >> (super les expressions hein ?) que mon appli, donc plus d'erreur.
 
Merci aux 20 personnes qui ont lu mon message. :-)
A la prochaine.


Message édité par Celiphane le 29-03-2007 à 11:58:27
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed