11
votes

Dois-je utiliser des threads ou des tâches - simulation de plusieurs clients

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.

Tous les clients simulés Exécutent la même routine après la connexion au serveur.

À tout moment, je voudrais simuler 300 à 800 clients à l'aide de mon programme.

Ma question est la suivante: Devrais-je créer n instances de classe client et les exécuter dans n threads différents? Ou

devrais-je utiliser la bibliothèque de tâches pour faire les choses?


4 Réponses :


1
votes

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?


0 commentaires

2
votes

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:

  1. Si vous souhaitez avoir 800 clients connectés, mais pas nécessairement en même temps, c'est une bonne idée d'utiliser tâche s. Ils sont légers et utilisent efficacement le threadpool sous-jacent .

  2. 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 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 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 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.


0 commentaires

1
votes

pour cette domaines d'application < / em> sont votre meilleur pari.

Un domaine d'application 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.

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.

pour ce que vous voulez avoir deux options.

  1. Démarrez X threads sur un thread séparé dans le même domaine.

    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. <00>

  2. Démarrez X threads dans le même processus dans son propre domaine d'application.

    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.

    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:

    Un exemple de 40 simulations de clients simultanents pourrait vous être utile: xxx

    J'espère que cela aide.


0 commentaires

23
votes

Vous ne devez certainement pas créer 800 threads.

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.

Vous souhaitez simuler 800 clients afin de tester le serveur.

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.

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.

Ce serait une solution ludicrous dans la vie réelle. Les fils, comme les gens, sont incroyablement chers . Vous devriez minimiser le nombre de threads que vous créez.

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?

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.

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.

La bonne solution consiste à embaucher deux personnes.

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é.

Ce que vous devriez faire est soit (1) obtenir la version bêta de C # 5 et utilisez async / attendre 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.

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. location deux personnes, une pour regarder la boîte aux lettres et une pour écrire les lettres.


1 commentaires

Et si elles sont longues interactions avec le serveur?