Je développe une application client/serveur WCF et le client appelle le serveur de manière asynchrone en encapsulant l'appel au Task.Factory.StartNew
et en utilisant une continuation pour appeler un délégué fourni par l'utilisateur au retour de l'appel WCF. L'opération du serveur effectue (entre autres) des E/S série avant de renvoyer une réponse au client. Le service utilise également un BlockingCollection pour mettre en file d'attente ces demandes, s'assurant qu'elles sont exécutées une à la fois pour éviter les conflits de port série. En l'état, l'application fonctionne parfaitement, même lorsque le client envoie une série de requêtes au serveur en succession rapide. Maintenant, l'application peut également être configurée pour fonctionner en mode "direct", où le client référence directement les assemblages côté serveur (pour des raisons de performances, si le client et le serveur sont sur le même PC). Dans ce scénario, le client utilise une instance de la classe de service (plutôt qu'un proxy créé par ChannelFactory) et appelle sa méthode d'opération directement, en utilisant le même assistant asynchrone Task.Factory.StartNew
.Étrangeté multithread
Dans ce mode "direct", je trouve que l'exécution côté serveur semble se dérouler lentement (il manque des données de port série), comme si elle était interrompue d'une manière ou d'une autre. Je peux "réparer" en changeant la tâche côté client pour utiliser TaskCreationOptions.LongRunning
. Malheureusement, cela casse alors l'application en "mode WCF", qui semble souffrir des mêmes problèmes de lenteur.
Maintenant, je pourrais simplement inclure le TaskCreationOptions (ou pas) en fonction du "mode" que l'application utilise, mais je voudrais comprendre pourquoi cela se produit en premier lieu. Des idées?
Modifier: Je remarque que le problème lors du démarrage de l'application lorsque le client envoie une douzaine de requêtes au serveur l'un après l'autre, dans une boucle for
. Après cela, le client interroge le serveur toutes les demi-secondes - ceci n'est pas affecté par le problème, et les deux autres minuteurs de threads qui exécutent le côté client et côté serveur (dont un se déclenche toutes les 65ms!). Je suis tombé sur un article indiquant que le pool de threads créera de nouveaux threads jusqu'à ce que le nombre minimum de threads soit atteint, après quoi il limite le nombre de threads créés à un par 500 millisecondes. Cela correspond aux symptômes de mon problème car je vois la lenteur frapper environ toutes les demi-seconde. Je vais refactoriser mon code côté client pour éviter de frapper le serveur tant de fois de suite, ce qui est dommage. Je voulais vraiment déclencher toutes ces requêtes l'une après l'autre, puis gérer les résultats dans les délégués de rappel une fois qu'ils avaient été traités par le serveur. Mais avec cette fonctionnalité "thread" il semble que je ne peux pas faire cela.
Première spéculation sauvage qui vient à l'esprit est que cette classe proxy sur le côté direct fait des choses en coulisses - encore inconnu - que la version de l'instance directe ne l'est pas. C'est là que je commencerais à chercher, au moins ... –
Pourriez-vous partager une instance d'un objet entre votre client/serveur? En mode WCF, vous ne partagerez pas l'instance, en mode direct, vous pourriez l'être, et vous pourriez avoir un problème avec cela? – jasper
@ jasper le lien est fait à travers un projet "facade" - le client fait référence à cet assembly mais pas directement au serveur. –