ThreadPool avec 1000 requetes [Résolu]

darkolite 12 Messages postés mardi 20 juillet 2004Date d'inscription 24 novembre 2006 Dernière intervention - 27 sept. 2006 à 15:54 - Dernière réponse : MorpionMx 3489 Messages postés lundi 16 octobre 2000Date d'inscription 30 octobre 2008 Dernière intervention
- 29 sept. 2006 à 09:41
Bonjour messieurs (dames?)

Je lutte depuis pas mal de temps avec le ThreadPool en C#. Je ne sais pas si c'est d'ailleurs la meilleurs solution. Voila ce que je voudrait faire.

Je récupére une liste de pages internet a récuperer, disons 1000 urls.

J'ai mon code qui fonctionne très bien, pour une url donnée, mon code récupère la page web, la parse pour prendre uniquement les infos qui m'interresse, puis enregistre ces données dans une base de donnée. Un peu a la maniere d'un crawler.

Lorsque je lance ma boucle sur les 1000 urls, ce systeme fonctionne très bien.

J'ai donc décidé de l'optimiser en gagnant du temps. Je voudrai lancer 20 Threads au lieu d'un, et dès qu'un de ces Threads a fini, il reprend le travail avec une nouvelle urls, pour traité les 980 urls suivantes.

Je me suis donc interressé au ThreadPool, car si je comprend bien, c'est justement son but. Je lance mon programme et voila ce qu'il m'arrive : Un beau message d'erreur :

"There were not enough free threads in the ThreadPool object to complete the operation."

Ok, je me renseigne sur le net, j'essaie differente facon, je mets des Thread.sleep partout pour voir comment ca marche... Rien pas moyen.

Je viens de faire un dernier Test, j'ai enlever toutes mes requetes webs, leurs traitements et l'insertion en base, et je l'ai remplacer par un  "Thread.Sleep(1000);" Et Surprise, tout a l'air de fonctionner !!! Mon Thread pool est plein assez rapidement, mais quand il est plein il plante pas... il continue avec ces 25 Threads par defaut.

Quelqu'un a une idee d'ou ca peut venir ?

Merci pour votre aide.

Yann
Afficher la suite 

Votre réponse

15 réponses

Meilleure réponse
MorpionMx 3489 Messages postés lundi 16 octobre 2000Date d'inscription 30 octobre 2008 Dernière intervention - 27 sept. 2006 à 16:55
3
Merci
Cela ressemble a ton souci
http://support.microsoft.com/default.aspx?scid=kb;en-us;815637

Tu as l'erreur en executant l'exemple de code ?

Mx
MVP C# 

Merci MorpionMx 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 74 internautes ce mois-ci

Commenter la réponse de MorpionMx
Meilleure réponse
MorpionMx 3489 Messages postés lundi 16 octobre 2000Date d'inscription 30 octobre 2008 Dernière intervention - 27 sept. 2006 à 17:54
3
Merci
Tu n'as pas possibilité de passer en .Net 2 ? Parce que cela a l'air de fonctionner sans erreur.

Mx
MVP C# 

Merci MorpionMx 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 74 internautes ce mois-ci

Commenter la réponse de MorpionMx
Meilleure réponse
darkolite 12 Messages postés mardi 20 juillet 2004Date d'inscription 24 novembre 2006 Dernière intervention - 29 sept. 2006 à 09:31
3
Merci
Pour finir, je voulais juste dire que pour mon probleme initiale de ThreadPool qui plante avec plus de requete de que Thread max dans le pool, est résolut :

La solution : Passer en . net 2.0., en 1.1 ya pas moyen.

Merci darkolite 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 74 internautes ce mois-ci

Commenter la réponse de darkolite
MorpionMx 3489 Messages postés lundi 16 octobre 2000Date d'inscription 30 octobre 2008 Dernière intervention - 27 sept. 2006 à 16:38
0
Merci
Salut


En effet, c'est une bonne idée d'utiliser le pool de Thread.
Celui-ci contient donc 25 Threads / CPU par defaut, et tu peux modifier cette valeur via la méthode SetMaxThreads. Tu peux aussi obtenir le nombre de Threads dispos via la méthode GetAvailableThreads

L'erreur que tu sembles avoir est bizarre, sachant que si il n'y a pas de Thread dispos, les demandes sont mises en file d'attente. D'ailleurs, avec ton dernier essai, ca prouve bien que ca devrait marcher.

On peut avoir un extrait de ton code qui plante, pour voir si y'a pas quelque chose qui cloche ?





Mx
MVP C#
 
Commenter la réponse de MorpionMx
darkolite 12 Messages postés mardi 20 juillet 2004Date d'inscription 24 novembre 2006 Dernière intervention - 27 sept. 2006 à 17:52
0
Merci
C'est tout a fait ca. J'ai repris le code de http://support.microsoft.com/default.aspx?scid=kb;en-us;815637, ceci produit la même erreur.

Sauf qu'il préconise d'augmenter le nombre max de thread. Je vais pas le passer a 1000 !!!

J'ai repris leurs code (avec 55 demandes de Thread), si l'on enleve la requete web ca fonctione, on voit le ThreadPool se remplir et finir avec zéro Thread de libre.
Je reteste en rajoutant la requete web... et arrivé a zéro on retrouve l'erreur. "There were not enough free threads in the ThreadPool object to complete the operation."
Je reteste  et cette fois ci je passe  seulement 20 demandes de Threads. Ca fonctionne, normal on a pas encore rempli le Thread.

Alors pourquoi lorsque le ThreadPool est plein, et qu'on ordonne une requete HttpWebRequest ca plante ?

Mystère mystère.

Si vous voyez une autre solution de gestion de thread automatique... ou un syteme pas trop compliqué...

Merci
Commenter la réponse de darkolite
MoDDiB 546 Messages postés mardi 26 novembre 2002Date d'inscription 4 mai 2007 Dernière intervention - 27 sept. 2006 à 17:54
0
Merci
Au niveau performance je doutes que tu gagnes réellement quoi que ce soit en utilisant des threads : disons qu'habituellement tu mets 1s par page internet et bien pour 10 threads tu mettras 10s pour qu'ils soient tous terminés : où est le gain ? Ou alors avec un dualCore .Net disperse la charge ?
Si quelqu'un de bien renseigné à une réponse :)
Commenter la réponse de MoDDiB
darkolite 12 Messages postés mardi 20 juillet 2004Date d'inscription 24 novembre 2006 Dernière intervention - 28 sept. 2006 à 10:17
0
Merci
Mes requetes mettent 3s en moyenne, pour ensuite moins d'une seconde de traitement/insertion en base. Si je lance 10 requetes en 10s, jvais attendre a peu pres 13 - 15 secondes en tout pour les réponses (c'est vraiment approximatif ce que je dis la), par contre une a une ca fait 10 X 3 soit 30 secondes.

Sur 10 requetes c'est pas très significatif, sur 1000 je pense franchment gagné 30% de tps.

Jvais tester mais pour moi ya pas photo, il vaut mieux balancer 10 resquetes et attendre les réponses que de tout faire une par une. Je me trompe ?

Je ne parle pas du tps de traitement, dual core et tout le reste, vu que le tps de récup des pages est beaucoup plus long, je peux traité 3 ou 4 pages (sans doute plus) pendant que j'en récupère qu'une seule page....

Mais si tu veux des renseignements regarde ce site : http://www.codeproject.com/cs/threads/smartthreadpool.asp

Yann
Commenter la réponse de darkolite
MoDDiB 546 Messages postés mardi 26 novembre 2002Date d'inscription 4 mai 2007 Dernière intervention - 28 sept. 2006 à 11:04
0
Merci
Donc d'après ce que tu dis plus j'utilises de Thread et plus mon programme occupera le processeur : ce qui veut dire que sans Thread le processeur n'est pas exploité à fond ....
J'aimerais des renseignements de la part d'un connaisseur mais je crois que je vais faire mes tests dans la journée :)
Commenter la réponse de MoDDiB
MoDDiB 546 Messages postés mardi 26 novembre 2002Date d'inscription 4 mai 2007 Dernière intervention - 28 sept. 2006 à 11:36
0
Merci
Dans ton cas précis effectivement je crois que tu peux gagner du temps vu qu'il y a la latence : pendant l'envoie ou la reception de la requete ton programme pourra travailler sur un autre site.

Car dans un autre cas si on te donne 2 projets à faire d'une durée d'une heure chacun et bien en les faisant en même temps ( Threads ) tu mettras tout de même 2 heures...

Mais je viens d'effectuer un test en remplissant un Form avec SetPixel suivit de ce petit calcul :
int a = 0;
for (int i = 0; i < 1000000000; i++)
{
if (i % 2 == 0)
a += i;
else
a -= i;
}

Et bien en éxécutant les méthodes à la suite elles sont éxécutés en 32s et en utilisant un Thread tout le traitement est terminé en 30s : comment cela est-il possible ?
Commenter la réponse de MoDDiB
darkolite 12 Messages postés mardi 20 juillet 2004Date d'inscription 24 novembre 2006 Dernière intervention - 28 sept. 2006 à 11:56
0
Merci
Oui et non. Grace au multithreading tu peux faire autre chose en parallele et donc occuper ton proc pendant qu'une autre parti de ton code attend qq chose. Mais bon, avec un seul thread j'arrive aussi a prendre 100% de mon CPU.... Tout dépend de ce que tu fais (acces disques, attente, web, action utilisateur...)

Par contre le fait de mettre le plus possible de Thread ne te garantit pas de meilleurs perf. Pour reprendre mon cas, j'ai 1000 pages web a récupérer, je ne vais pas bourrer mon Thread Pool de thread ca sert a rien, en plus le systeme est limité en nombre de thread et en nombre de connection TCP simultané (50 sous XP je crois). Je vais faire des tests, mais je pense utiliser un Thread Pool de 3 à 10 Threads max. Je ferai le test chronométré pour voir avec combien de Thread j'arrive a faire mes taches le plus rapidement possible.

Apres t'as raison, ca devient hors de mes competences. Je suis pas expert.

Si je me souviens bien, le ThreadPool de base n'est pas le plus efficace en terme de perf, il faudrait que je retrouve le site qui en parle. Ils ont fait des tests avec diverses methodes, tps de traitement, optimisation etc ...)

Yann
Commenter la réponse de darkolite
MoDDiB 546 Messages postés mardi 26 novembre 2002Date d'inscription 4 mai 2007 Dernière intervention - 28 sept. 2006 à 12:20
0
Merci
Ok j'attends des chiffres de ton boulot :)
Commenter la réponse de MoDDiB
darkolite 12 Messages postés mardi 20 juillet 2004Date d'inscription 24 novembre 2006 Dernière intervention - 28 sept. 2006 à 16:50
0
Merci
Voila, j'ai fait qq test. J'ai repris le code de crosoft que j'ai légérement modifié.

            int intThread = 50;
            ThreadPool.SetMaxThreads(intThread, 9000);

            int intPages = 1000;
            for (int i = 0; i < intPages; i++)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(PoolFunc), i);
            }

J'ai fait varié la variable intThread avec les valeurs suivante 1, 5, 10, 20, 50
J'ai fait varié la variable intPages avec les deux valeurs suivante : 100 pages et 1000 pages

Voici ce que ca donne en graphe, l'axe Y représente le tps de traitement totale en seconde, l'axe X le nombre de Thread utilisé dans mon ThreadPool.
La serie 1 correspond à 100 pages
La serie 2 correspond a 1000 pages

J'ai fait 3 test pour chacun des points et j'ai fait une moyenne. La ou j'ai un peu de mal a certifié la véracité de mes résultats c'est que je ne suis pas maitre d'internet, des taux de transfert, de la bande passante, de la disponibilité du réseaux etc.
Donc a prendre avec des pincettes.

On voit le tps de traitement plus faible d'environ 40 % avec un pool de thread a 20. J'annonce aucune conclusion car j'ai fait ca rapidos. On remarque aussi qu'avec un pool de 50 ca met autant de tps qu'avec un pool de 10.

Le second graph affiche le traffic moyen observé pendant l'analyse. Pareil, c'est avec a le pool a 20 qu'on observe la meilleure vitesse. Normal, pour la meme quantité de donnée, comme on a mit moins de tps, on a un meilleur telechargement moyen. (unité le kpb)

Voila, ca sert pas a grand chose, mais j'ai fait le test !

Yann
Commenter la réponse de darkolite
MoDDiB 546 Messages postés mardi 26 novembre 2002Date d'inscription 4 mai 2007 Dernière intervention - 28 sept. 2006 à 18:33
0
Merci
Merci pour ces jolis graphique.
Très intéressant de voir tout ca :)
Commenter la réponse de MoDDiB
Moomoon07 223 Messages postés mercredi 31 mai 2006Date d'inscription 5 mai 2014 Dernière intervention - 28 sept. 2006 à 21:28
0
Merci
Très instructif ... .
Moi je m'étais pris la tête une fois avec un truc de ce genre, mais avec du lan et des requêtes SQL. C'était comique...

MN
Commenter la réponse de Moomoon07
MorpionMx 3489 Messages postés lundi 16 octobre 2000Date d'inscription 30 octobre 2008 Dernière intervention - 29 sept. 2006 à 09:41
0
Merci
Ouep, voir ce que je disais en page precedente.


Si t'as pu switcher sur l'autre framework, alors tant mieux :)
Je valide ta réponse ;)





Mx
MVP C#
 
Commenter la réponse de MorpionMx

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.