J'écris un programme de simulation de client dans lequel tous les clients simulés exécutent une routine prédéfinie contre Server - qui est un serveur Web exécutant dans Azure avec quatre instances. P>
Tous les clients simulés Exécutent la même routine après la connexion au serveur. P>
À tout moment, je voudrais simuler 300 à 800 clients à l'aide de mon programme. P>
Ma question est la suivante: Devrais-je créer n instances de classe client et les exécuter dans n threads différents? Ou p>
devrais-je utiliser la bibliothèque de tâches pour faire les choses? P>
4 Réponses :
J'utiliserais la bibliothèque de tâches et je laisserais la bibliothèque de tâches gérer tout le filetage pour vous. Vous ne voulez pas faire tourner 800 threads. C'est une mauvaise idée d'avoir que de nombreux threads simultanés allant à la fois, voici une autre question de dépassement de pile qui parle de cela: Nombre maximum de threads dans une application .NET? P>
La réponse dans ce cas n'est pas si simple. Cela dépend vraiment de la façon dont vous voulez que vos clients à simuler: p>
Si vous souhaitez avoir 800 clients connectés, mais pas nécessairement en même temps, c'est une bonne idée d'utiliser Si vous voulez vraiment que les clients soient absolument tous en parallèles, j'ai peur qu'il n'y ait aucun moyen d'éviter réellement les threads. Il n'y a pas de moyen magique d'obtenir 800 tâches d'exécution simultanées légères. La tâche tâche code> s. Ils sont légers et utilisent efficacement le threadpool
sous-jacent code>. P> li>
code> L'abstraction est légère précise, car elle utilise le pool de threads. Cela signifie que de nombreuses tâches sont mappées sur un petit nombre de threads réels. Mais, bien sûr, cela implique qu'ils ne fonctionnent pas vraiment en parallèle, mais sont plutôt prévus de courir chaque fois que possible. Le
threadpool code> a un nombre maximal de filets de 250 (AFAIK), donc pas plus de 250 "clients" exécuteront en même temps si vous utilisez une tâche
code> s. La solution est définie des threads max sur 800, mais à ce stade, c'est la même chose que d'utiliser des threads classiques. P> li>
ol>
pour cette domaines d'application < / em> sont votre meilleur pari.
Un domaine d'application em> est l'unité d'isolement d'exécution dans laquelle une application .NET exécute. Il fournit une limite de mémoire gérée, un conteneur pour les paramètres de configuration d'application, ainsi que la fourniture d'une interface de communication pour les applications distribuées. P> Chaque application .NET héberge généralement un domaine d'application qui est automatiquement créé par le CLR. Compte tenu du processus / du programme commence. Il est parfois utile (dans une affaire telle que la vôtre) de créer des domaines d'application supplémentaires avec un seul processus / programme. L'utilisation de plusieurs domaines d'application évite les complications de la communication et surgir à l'aide de plusieurs processus individuels et assure une isolation de vos tâches. P> pour ce que vous voulez avoir deux options. P> Cela signifie que vous devrez être très fatigué d'être le fil-sûr, qui sera très difficile avec une telle tâche de simulation de plusieurs connexions, simulez les clients, etc. P> <00>
Cela gardera chacun des threads filés isolés et également faciles à accéder par l'application d'hébergement / programme. En vous suffisant X simulation x dans x domaines d'application distincts, chaque domaine serait isolé et incapable d'interférer avec une autre simulation client via des membres de la classe statique, etc. p> les éléments suivants sont assistés par un extrait de Le livre de Joseph Albahari C # 4.0 en un mot de texte que je recommande vivement à obtenir: em> p> Un exemple de 40 simulations de clients simultanents pourrait vous être utile: p> J'espère que cela aide. p> p>
Vous ne devez certainement pas créer 800 threads. p>
Prenons un pas en arrière ici. Vous avez un appareil appelé "serveur" qui prend des "demandes" à partir de "clients" et envoie des "réponses" à ces clients. Supposons que les demandes soient des pièces de papier livrées par le bureau de poste et les réponses sont des boîtes contenant des livres, également livrées par le bureau de poste. P>
Vous souhaitez simuler em> 800 clients afin de tester le serveur. p>
Supposons que le fil est une personne et qu'un processeur est une chaise. Une personne ne peut faire que travailler tout en étant assis sur la chaise. P>
Créer 800 threads est l'équivalent de sortir et de recruter 800 personnes et de payer chacune d'elles à envoyer une lettre au serveur. Mais vous n'avez que quatre chaises, de sorte que ces 800 personnes doivent tous faire tourner à tour de rôle avec les chaises. P>
Ce serait une solution ludicrous em> dans la vie réelle. Les fils, comme les gens, sont incroyablement chers em>. Vous devriez minimiser le nombre de threads que vous créez. P>
Donc, si vous créez plutôt 800 tâches via l'usine de tâche et laissez le tonne de la parallèle pour vous? P>
Non, vous ne devriez pas faire cela non plus. Le TPL a une piscine de personnes (fils) à tirer de, et il essaie d'organiser des choses afin qu'il n'y ait plus de gens sur la masse salariale que des chaises pour eux de s'asseoir. Mais votre tâche n'est pas "chaise lié" - - Les gens vont s'asseoir sur la chaise, envoient la demande au serveur, puis sortir de la chaise pendant qu'ils attendent que la réponse revienne. pendant qu'ils attendent, le TPL doit maintenant embaucher plus de personnes pour entretenir les tâches supplémentaires. strong> p>
frapper un serveur Web est I / O lié; Vous ne devez créer que des tâches de filetage pour les tâches liées à la CPU. strong> p>
La bonne solution consiste à embaucher deux em> personnes. p>
Une personne - le "thread d'achèvement d'E / S" - ne fait que déposer des demandes dans la boîte aux lettres et vérifier les packages entrants. L'autre personne - la personne "Simulation" - travaille sur ce que le bon "calendrier" est destiné à simuler 800 clients. La personne de simulation travaille sur l'horaire, puis se couche. Elle se réveille quand il est temps d'envoyer une autre demande au serveur. Quand elle se réveille, elle raconte le thread d'achèvement d'E / S pour déposer cette lettre dans la boîte aux lettres et la réveiller lorsque la réponse s'arrête alors qu'elle s'endormit jusqu'à ce qu'il soit temps d'envoyer une autre demande ou une réponse vient dans cela doit être vérifié. p>
Ce que vous devriez faire est soit (1) obtenir la version bêta de C # 5 et utilisez En bref: la bonne façon de gérer de nombreuses tâches parallèles d'E / S est de créer un très petit nombre de discussions, chacune d'une très petite quantité de travail à la fois. Laissez le thread d'achèvement d'E / S gérer les détails de l'E / S. Vous n'avez pas besoin de recruter 800 personnes afin de simuler l'envoi de 800 lettres. strong> location deux em> personnes, une pour regarder la boîte aux lettres et une pour écrire les lettres. P> async / attendre code> pour créer des tâches qui envoient des demandes au serveur, puis remplissez le contrôle de la boucle du message. Jusqu'à ce qu'il soit temps d'envoyer une autre demande ou une réponse est entrée. Ou, si vous ne souhaitez pas utiliser C # 5, vous devez créer une source d'achèvement de la tâche et configurer les tâches qui ont les bonnes continissions. p>
Et si elles sont longues interactions avec le serveur?
Voir la discussion sur la discussion ici