utilisation du processeur augmente jusqu'à 100% dans une boucle infinie dans le thread
Je suis d'exécution un basé sur le web plate-forme de chat en ASP.NET Application Web, et j'utilise une technique similaire, le temps d'interrogation. Je veux dire, je garde chaque requête web à partir d'un client pour une période de temps spécifique(délai d'attente) ou jusqu'à ce qu'un nouveau message arrive, et puis la réponse est envoyée au client.
- Je garder les clients connectés en mémoire(dictionnaire de l'objet) et quand un nouveau message est envoyé à un client, j'écris ce message dans le récepteur client messages du tableau.
Le Client doit envoyer une requête pour obtenir ses propres messages, et je garde cette requête dans un tableau en mémoire.
Je suis à l'aide de http asynchrone gestionnaire pour les écoutes la demande du client, je suis en gardant les requêtes web dans un tableau en mémoire. J'ai utiliser des threads pour vérifier les nouveaux messages de façon continue à partir de la mémoire (dans le dictionnaire, qui est créé pour chaque client).
Je ne l'utilise pas .net le pool de threads pour vérifier les nouveaux messages ou dépassé les requêtes web.Je créer des threads comme ceci:
System.Threading.Thread t = new Thread(new ThreadStart(QueueCometWaitRequest_WaitCallback));
t.IsBackground = false;
t.Start();
Dans chaque thread QueueCometWaitRequest_WaitCallback méthode, je suis dans une boucle while infinie:
while (true)
{
...
Thread.Sleep(100);
}
Dans cette méthode, je vérifie pour le web demande du temps ou un nouveau message pour chaque Requête Web qui est également conservée dans un tableau en mémoire.
Tout fonctionnait bien jusqu'à ce que j'ai remarqué que l'utilisation du PROCESSEUR atteint jusqu'à 100% dans le temps. (en minutes après le premier client connecté)
Au début de la première demande, tout semble être normal, je veux dire l'utilisation de l'UC n'est pas supérieur à 10%, tandis que le retour d'une réponse au client. Mais dans le temps même avec 2 clients l'utilisation de l'UC augmente jusqu'à 100%. Il semble que l'utilisation du PROCESSEUR est à 100% que lors de l'écriture d'une réponse pour une demande d'un client. Si aucun client n'est de gauche puis tout retour à la normale (utilisation du PROCESSEUR est d'environ 0%) jusqu'à ce nouveau site web demande est effectuée par un client.
Je ne sais pas les fils dans le détail, mais je suis méfiant sur les nouvelles discussions que j'ai créé et fonctionne à l'infini. C'est comme le système d'exploitation donne plus l'utilisation du PROCESSEUR et de la ressource dans le temps puisqu'ils travaillent tout le temps, et ce Fil.Sleep(100) ne fonctionne pas.
Ici est la QueueCometWaitRequest_WaitCallback() méthode:
void QueueCometWaitRequest_WaitCallback()
{
while (true)
{
if (processRequest.Length == 0)
{
Thread.Sleep(100);
}
else
{
for (int i = 0; i < processRequest.Length; i++)
{
Thread.Sleep(100);
//below I am checking for new message or request time out
.................
.................
//If new message or time out I write to response
}
}
}
}
J'espère que je pourrais lui expliquer la situation, et je suis ouvert à toute suggestion (comme la mise en oeuvre d'une manière différente)
Si vous pouvez m'aider avec ce problème je vous en seront reconnaissants gratitude,
Grâce
System.Threading.Timer
/System.Timers.Timer
qui wuld déclencher toutes les N millisecondes.Est-ce approximativement ce que vous voulez accomplir? while (true){ Thread.Sleep(100); foreach(var req processRequest){performProcessRequest(req);} processRequest.Supprimer(r=>r.RequestCompletedOrTimedOut);}
J'ai besoin de retourner la réponse à un client (nouveau message) ASAP <br/> Puisque c'est une application de chat, le délai de vérification ne devrait pas être trop long, je pense qu'elle doit être plus petite que 1 seconde si je utiliser une Minuterie?
no Oni: Vous avez raison, j'ai besoin de délai d'expiration ainsi même pas de nouveau message
OriginalL'auteur Mehmet | 2012-01-16
Vous devez vous connecter pour publier un commentaire.
Tout comme les meilleures pratiques commentaire par opposition à réponse directe, - il n'est pas advisbable écrire un Fil.Sleep(100) à l'intérieur de votre récepteur de messages du fil. Une meilleure méthode serait d'utiliser Thread.Rejoindre comme mentionné précédemment ou ManualResetEvent attendre poignées. Par exemple, vous pourriez code comme ceci:
Cela permettrait de s'assurer que votre thread utilise 0% de CPU pendant l'attente et ne consomme du CPU quand il y a du travail à faire.
À défaut, avez-vous pensé à un tiers solution asynchrone bi-directionnelle de messagerie? J'ai utilisé RabbitMQ (AMQP) avec un grand succès .NET applications pour gérer le débit de messagerie. L'API pour RabbitMQ signifie que vous obtenez un événement lorsqu'un message a été reçu, qui peuvent alors être traités sur un thread d'arrière-plan.
Cordialement,
Pas de probs. Juste a penser - vous ne devriez pas obtenir 100% de CPU à partir de votre exemple de code. Le nombre de threads que vous êtes en train de créer? (Juste une intuition). devrait être l'une des cours! Ce n'est pas l'un par demande est-il?
Pas un par demande, pour un Total de 5 threads. Les demandes sont dans un tableau
Je recommande vivement se regarder dans RabbitMQ, en tant que tiers de messagerie asynchrone solution. Cela permettra de gérer message tuyaux entre point à point (un client, un serveur), multi-cast (serveur à tous les clients) avec une faible utilisation du CPU, de haut débit. Vous pourriez implemement un état périodique de mise à jour pour tous les clients par la mise en œuvre d'une Minuterie sur le serveur qui, si pas de nouvelles notifications ont été reçues, a envoyé un message à tous les clients.
Merci encore, je vais regarder RabbitMQ, mais malheureusement, nous avons notre site web ouvert et je ne sais pas si je peux changer la mise en œuvre totalement dans RabbitMQ
OriginalL'auteur Dr. ABT
Dictionnaire des objets ne sont pas thread-safe si elle est utilisée de manière statique. Si l'utilisant comme un membre statique alors vous avez besoin pour créer une instruction Lock.
Voici un exemple levé du Log4Net LoggerFactory classe...Notez que le TypeToLoggerMap est un dictionnaire d'objet et quand il est référencé vai le GetLogger méthode, une instruction Lock est utilisé.
Vérifier cet article - c'est là que j'ai découvert l'info ci-dessus à propos du Dictionnaire des objets.
https://www.toptal.com/dot-net/hunting-high-cpu-usage-in-dot-net
Comme une note de côté, avez-vous envisagé de SignalR pour votre projet?
OriginalL'auteur Wayne Feltham