2009-05-23 13 views
19

J'essaie d'implémenter un moteur de balayage Web limité en C# (pour quelques centaines de sites seulement) en utilisant HttpWebResponse.GetResponse() et Streamreader.ReadToEnd(), également essayé en utilisant StreamReader.Read() et une boucle pour construire ma chaîne HTML.HTTPWebResponse + StreamReader Très lent

Je ne télécharge que des pages d'environ 5-10K.

Tout est très lent! Par exemple, le temps moyen GetResponse() est d'environ une demi-seconde, alors que le temps moyen de StreamREader.ReadToEnd() est d'environ 5 secondes!

Tous les sites doivent être très rapides, car ils sont très proches de mon emplacement et ont des serveurs rapides. (dans l'Explorateur ne prend pratiquement rien à D/L) et je n'utilise aucun proxy.

Mon Crawler possède environ 20 threads qui lisent simultanément depuis le même site. Cela pourrait-il causer un problème?

Comment réduire les temps de StreamReader.ReadToEnd DRASTIQUEMENT? DownloadString de WebClient est un wrapper simple pour HttpWebRequest, pourriez-vous essayer de l'utiliser temporairement et voir si la vitesse s'améliore?

Répondre

8

Si les choses vont beaucoup plus vite, pourriez-vous partager votre code afin que nous puissions voir ce qui ne va pas?

EDIT:

Il semble HttpWebRequest observe le réglage 'connexions simultanées max' IE, sont ces URL sur le même domaine? Vous pourriez essayer d'augmenter la limite des connexions pour voir si cela aide? J'ai trouvé this article sur le problème:

Par défaut, vous ne pouvez pas effectuer plus que 2-3 async HttpWebRequest (dépend du système d'exploitation). Pour la remplacer (la façon la plus simple, à mon humble avis) n'oubliez pas ajouter cette application de l'article dans la configuration fichier de l'application:

<system.net> 
    <connectionManagement> 
    <add address="*" maxconnection="65000" /> 
    </connectionManagement> 
</system.net> 
+0

essayé d'utiliser WebClient, les mêmes résultats (le temps moyen n'a pas changé). Je devrais aussi mentionner que j'ai une connexion de 1.5MBPS avec une vitesse d/l moyenne de 180KBPS Je pensais que peut-être 20 threads appelant tous StreamReader.Read en même temps pourrait avoir quelque chose à voir avec elle? Ou est-ce non pertinent? – Roey

+0

Dans mon expérience, sur une connexion comme ça, vous allez saturer la bande passante avec 3-4 threads. Pas besoin de courir plus à moins que les sites que vous ping sont vraiment lents et que vous ayez des threads qui dorment beaucoup, attendant des E/S. – kgriffs

+1

wow !!! J'utilisais async HttpWebRequest pour charger le serveur de test avec environ 300 threads par client et chaque thread était en train de télécharger "en série". En changeant le paramètre maxconnection, chaque thread a téléchargé les données 10 fois plus vite. –

15

HttpWebRequest peuvent prendre un certain temps pour détecter votre proxy settings . Essayez d'ajouter ceci à votre configuration d'application:

<system.net> 
    <defaultProxy enabled="false"> 
    <proxy/> 
    <bypasslist/> 
    <module/> 
    </defaultProxy> 
</system.net> 

Vous pouvez également voir un léger gain de performances de mise en mémoire tampon de votre lit pour réduire le nombre d'appels à la prise du système d'exploitation sous-jacent:

using (BufferedStream buffer = new BufferedStream(stream)) 
{ 
    using (StreamReader reader = new StreamReader(buffer)) 
    { 
    pageContent = reader.ReadToEnd(); 
    } 
} 
+0

Merci! Cela a totalement accéléré mon code de quelques secondes à quelques millisecondes! –

+0

Quel est le code équivalent en C++? L'utilisation (...) ne fonctionne pas en C++ – Edge

1

Avez-vous essayé ServicePointManager.maxConnections? Je règle généralement à 200 pour des choses semblables à ceci.

1

J'ai eu le même problème mais le pire. response = (HttpWebResponse) webRequest.GetResponse(); dans mon code retardé environ 10 secondes avant d'exécuter plus de code et après cela, le téléchargement saturé ma connexion.

réponse de kurt defaultProxy activé = "false"

a résolu le problème.maintenant la réponse est presque instantanément et je peux télécharger n'importe quel fichier http à mes connexions vitesse maximale :) désolé pour le mauvais anglais

1

J'ai trouvé la méthode Application Config ne fonctionnait pas, mais le problème était encore en raison des paramètres de proxy. Ma demande simple pour prendre jusqu'à 30 secondes, maintenant il faut 1.

public string GetWebData() 
{ 
      string DestAddr = "http://mydestination.com"; 
      System.Net.WebClient myWebClient = new System.Net.WebClient(); 
      WebProxy myProxy = new WebProxy(); 
      myProxy.IsBypassed(new Uri(DestAddr)); 
      myWebClient.Proxy = myProxy; 
      return myWebClient.DownloadString(DestAddr); 
} 
4

J'ai eu le même problème, mais quand je me suis assis paramètre Proxy du HttpWebRequest null, il a résolu le problème.

UriBuilder ub = new UriBuilder(url); 
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(ub.Uri); 
request.Proxy = null; 
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
+0

Excellente solution! Travaille pour moi. –

0

Merci à tous pour les réponses, ils m'ont aidé à trouver la bonne direction. Je suis confronté à la même question de performance, bien que la solution proposée pour modifier le fichier de configuration de l'application (comme je l'ai compris que la solution est pour les applications web) ne correspond pas à mes besoins, est présenté ci-dessous ma solution:

HttpWebRequest webRequest; 

webRequest = (HttpWebRequest)System.Net.WebRequest.Create(fullUrl); 
webRequest.Method = WebRequestMethods.Http.Post; 

if (useDefaultProxy) 
{ 
    webRequest.Proxy = System.Net.WebRequest.DefaultWebProxy; 
    webRequest.Credentials = CredentialCache.DefaultCredentials; 
} 
else 
{ 
    System.Net.WebRequest.DefaultWebProxy = null; 
    webRequest.Proxy = System.Net.WebRequest.DefaultWebProxy; 
} 
0

Pourquoi le multithreading ne résoudrait-il pas ce problème? Le multithreading réduirait les temps d'attente sur le réseau et, puisque vous stockez le contenu du tampon dans la mémoire système (RAM), il n'y aurait pas de goulot d'étranglement pour les E/S en traitant avec un système de fichiers. Ainsi, vos 82 pages qui prennent 82 secondes à télécharger et à analyser, devraient prendre 15 secondes (en supposant un processeur 4x). Corrigez-moi si quelque chose me manque.

____ TÉLÉCHARGER FILET _____ *

Télécharger Sommaire

Formulaire flux

Lire Sommaire

_________________________ *

+0

L'OP indique déjà que les threads "d'environ 20" sont utilisés. – Spooky

Questions connexes