9
votes

Objets d'objets d'un concurrentqueur en C #

Hey, j'essaie de mettre en œuvre un concurrentqueur en C # pour un serveur asynchrone. Les articles sont en cours de file d'attente dès qu'un message complet est reçu. Pour déroger des messages, je fais un petit nombre de discussions pour faire le travail de dérobe et d'entretien des demandes. Ceci est insuffisant car chaque thread utilise une boucle tandis que, qui consomme plutôt une grande quantité de temps de processeur, pour des raisons évidentes.

Est-ce que quelqu'un voudrait connaître une méthode de désaction de messages si nécessaire mais ne consommant pas de temps de traitement. xxx


0 commentaires

4 Réponses :


22
votes

au lieu d'utiliser Concurrentqueue directement, avez-vous essayé de l'envelopper dans un blocagecollection ? Alors vous pouvez utiliser trytake (out t, tispan) , etc. Je crois que c'est l'utilisation attendue: que les collections simultanées elles-mêmes se habituellement sont là pour que vous puissiez sélectionner comment le La collection de blocage fonctionnera.

qui ne doit pas nécessairement être le seul utiliser pour ces collections bien sûr, mais en particulier pour Concurrentqueue , le scénario de la file d'attente du producteur / consommateur est le plus Common One - à quel point blockingcollection est le moyen de faciliter la tâche de faire la bonne chose.


9 commentaires

+1 Vous impliquez presque que les collections simultanées ne sont que là pour revenir blockingcollection et je ne suis pas sûr que c'est vrai. Mais vous êtes mort avec l'utilisation du blockingCollection ici pour minimiser toute la cérémonie pour aller avec les modèles de producteurs / consommateurs traditionnels.


@MARC: Je ne dirais pas que c'est tout à fait vrai de cette étendue, mais je pense que ce sera le prédominant . Je vais mettre à jour la réponse.


Salut, merci pour les suggestions! J'ai enveloppé mon concurrentqueur dans un blockingCollection et les résultats sont fantastiques. Je couronne 20 threads simultanément pour manger à travers la file d'attente, avec une durée de blocage de 0,1 seconde par fil via la méthode TyctAKe (OUT T, TIMPAN S), et il travaille un charme. Les demandes sont desservies dans un délai approprié (plus rapide que sans la concurrence) et la charge de la CPU n'a jamais été plus faible. Merci encore!


@ user352891: woot! C'est bon à entendre :)


Je pense que c'est le premier modèle de conception décent que j'ai lu, concernant Concurrentqueue .


@Jon Skeet: sondez-vous via une trychère le meilleur moyen d'y parvenir?


@sgtz: Cela me semble raisonnable, oui.


Cet emballage ne détruit pas l'ordre des objets? Concurrentqueue est décrit comme FIFO, BlockingCollection n'est pas


@Offler: BlockingCollection enveloppe une autre iProducerconsumerciollection , défaut sur Concurrentqueue Si vous ne spécifiez rien d'autre. Donc non, cela ne détruira pas de commander.



5
votes

Il y a un schéma bien connu dans une programmation simultanée appelée producteur parallèle / modèle de consommation. Cet article pourrait aider à résoudre certains de vos problèmes. http : //blogs.msdn.com/b/csharpfaq/archive/2010/08/12/blocking-collection-et-Tro-producer-consumer-problem.aspx


0 commentaires

3
votes

Vous pouvez utiliser un objet de verrouillage statique pour les fils à attendre, puis le pulsez lorsque quelque chose est prêt à être traité. XXX

Gardez à l'esprit que cela peut être assez compliqué avec le Plus de branches que vous avez, mais le gist de celui-ci est, vous verrouillez-vous sur un objet commun et appelez moniteur.wait pour attendre sur un objet pour être Pulse d. Lorsque cela ne se produit qu'un seul fil qui l'attendait sera libéré. Si vous en faisez beaucoup d'objets et que vous les souhaitez tous, vous pouvez appeler moniteur.pulsAll qui libérera toutes les threads qui attendaient sur l'objet.


1 commentaires

Bonjour, merci pour la suggestion! J'ai mis en œuvre votre suggestion et les résultats étaient très prometteurs avec un petit nombre de demandes. Toutefois, dès qu'il y avait un grand nombre de demandes à entretenir, le temps nécessaire pour répondre considérablement. Encore une fois, merci pour la suggestion, c'est certainement une technique que je garderai à l'esprit pour les projets futurs.



1
votes

La solution de blocageCollection est excellente. Sinon, il suffit de dormir, c'est probablement assez bon pour la plupart des cas. Il introduit un petit retard dans le temps de réponse, et il consomme une petite quantité de temps de traitement. L'avantage est un système plus robuste qui est plus facile à comprendre et moins susceptible d'échouer: xxx


3 commentaires

Je ne l'appellerais pas plus robuste que blockingcollection mais l'idée de dormir pendant inactif est un bon modèle d'étranglement couramment utilisé. Selon la critique, il est de traiter les données en temps réel et combien de ces processus ont été instanciés simultanément, vous pourriez également introduire un modèle de back-off supplémentaire dort, où le temps de sommeil augmente pour chaque itération où aucun iotems n'a été traité.


Je suis entièrement d'accord, BlockingCollection est au moins aussi robuste dans ce cas. En général, je voulais montrer ce modèle parce que cela revient souvent, et j'ai eu beaucoup mieux de chance au fil des ans avec le sommeil comme celui-ci au lieu d'une sorte de mécanisme de signalisation.


Désolé d'être critique @dwayne, je préfère réellement ce modèle pour la quasi-totalité de ma simple logique de traitement basée sur la file d'attente, je commençais juste à commenter la langue que vous avez utilisée. Ce qui n'est pas évident est le Magic Dormir (100) et quelques idées sur la manière de l'utiliser. et comment cela affecte les choses. Surtout parce que vous êtes prêt contre un poste de 11 ans de Jon, cela signifie que nous devrions mettre plus d'efforts pour la vendre au prochain lecteur.