65 votes

Essayer d'exécuter plusieurs requêtes HTTP en parallèle, mais en étant limité par Windows (registre)

Je suis du développement d'une application (winforms en C# .NET 4.0) où j'ai accès à une fonctionnalité de recherche à partir d'un 3ème partie par l'intermédiaire d'une simple requête HTTP. - Je appeler une url avec un paramètre, et en retour je reçois un petit string avec le résultat de la recherche. Assez Simple.

Le défi est cependant que j'ai à faire beaucoup de ces recherches (quelques milliers), et je voudrais limiter le temps nécessaire. Par conséquent, je tiens à exécuter les demandes en parallèle (disons de 10 à 20). J'utilise un pool de threads pour ce faire, et la version courte de mon code ressemble à ceci:

public void startAsyncLookup(Action<LookupResult> returnLookupResult)
{
 this.returnLookupResult = returnLookupResult;

 foreach (string number in numbersToLookup)
 {
  ThreadPool.QueueUserWorkItem(lookupNumber, number);
 }
}

public void lookupNumber(Object threadContext)
{
 string numberToLookup = (string)threadContext;
 string url = @"http://some.url.com/?number=" + numberToLookup;

 WebClient webClient = new WebClient();
 Stream responseData = webClient.OpenRead(url);

 LookupResult lookupResult = parseLookupResult(responseData);
 returnLookupResult(lookupResult);
}

- Je remplir numbersToLookup a List<String>) à partir d'un autre endroit, appelez - startAsyncLookup , et de lui fournir une fonction de rappel returnLookupResult de retour de chaque résultat. Cela fonctionne, mais j'ai constaté que je n'obtiens pas le débit que je veux.

Au départ, j'ai pensé qu'il pourrait être la 3e partie ayant un mauvais système sur leur fin, mais j'exclus en essayant d'exécuter le même code à partir de deux machines différentes en même temps. Chacun des deux a pris aussi longtemps que l'on n'a à lui seul, afin que je puisse exclure qu'un.

Un collègue puis à bout de moi que cela pourrait être une limitation de Windows. J'ai googlé un peu, et a trouvé, entre autres, ce post en disant que, par défaut, Windows limite le nombre de requête simultanée sur le même serveur web de 4 pour HTTP 1.0 et 2 pour HTTP 1.1 (HTTP 1.1 ceci est fait en fonction de la spécification (RFC2068)).

Le même poste visé ci-dessus a également fourni un moyen d'augmenter ces limites. Par l'ajout de deux valeurs de registre [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings] (MaxConnectionsPerServer et MaxConnectionsPer1_0Server), j'ai pu le contrôle de moi-même.

Donc, j'ai essayé ce samedi à la fois à 20), redémarré mon ordinateur, et j'ai essayé de lancer mon programme à nouveau. Hélas, cela ne semble pas aider tout. J'ai aussi gardé un œil sur le Moniteur de Ressource (voir capture d'écran) lors de l'exécution de ma recherche par lot, et j'ai remarqué que mon application (celui avec le titre masqués) encore qu'a l'aide de deux connexions TCP.

Donc la question est, pourquoi n'est-ce pas de travail? Est le poste que j'liés à l'utilisation de mauvaises valeurs de registre? Est-ce peut-être pas possible de "pirater" dans Windows plus (je suis sur Windows 7)?

Toutes les idées seront très appréciés :)

Et juste au cas où quelqu'un doit se demander, j'ai aussi essayé avec des paramètres différents pour MaxThreads sur le pool de threads (everyting de 10 à 100), et cela ne semble pas affecter mon débit à tous, donc le problème ne devrait pas être là non plus.

96voto

Incognito Points 10148

Il est question de ServicePoint. Qui fournit la gestion de la connexion pour les connexions HTTP. La valeur par défaut nombre maximal de connexions simultanées par un ServicePoint objet est de 2. Donc, si vous avez besoin de l'augmenter, vous pouvez utiliser ServicePointManager.DefaultConnectionLimit de la propriété. Il suffit de vérifier le lien dans MSDN là, vous pouvez voir un exemple. Et de définir la valeur dont vous avez besoin.

29voto

Matt Points 1705

Pour une référence plus rapide pour quelqu'un. Pour augmenter la limite de connexion par hôte, vous pouvez le faire dans votre Main () ou à tout moment avant de commencer à envoyer les requêtes HTTP.

    System.Net.ServicePointManager.DefaultConnectionLimit = 1000; //or some other number > 4
 

0voto

Gary Points 1410

Pour Internet Explorer 8: Exécutez l'Éditeur du Registre et accédez à la clé suivante: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTION SPERSERVER

et

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTION SPER1_0SERVER

Si FEATURE_MAXCONNECTIONSPERSERVER et FEATURE_MAXCONNECTIONSPER1_0SERVER sont manquantes, de les créer. Maintenant, créez la Valeur DWORD appelée iexplore.exe pour les deux sous-clés (voir ci-dessus) et de définir leur valeur de 10 ou quel que soit le nombre désiré.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X