2009-05-23 30 views
19

Estoy tratando de implementar un rastreador web limitado en C# (para unos pocos cientos de sitios solamente) usando HttpWebResponse.GetResponse() y Streamreader.ReadToEnd(), también intenté usar StreamReader.Read() y un bucle para construir mi cadena HTML.HTTPWebResponse + StreamReader Muy lento

Solo estoy descargando páginas de 5-10K.

¡Todo es muy lento! Por ejemplo, el tiempo promedio de GetResponse() es de aproximadamente medio segundo, mientras que el tiempo promedio de StreamReader.ReadToEnd() es de aproximadamente 5 segundos.

Todos los sitios deben ser muy rápidos, ya que están muy cerca de mi ubicación, y tienen servidores rápidos. (en Explorer no lleva prácticamente nada a D/L) y no estoy usando ningún proxy.

My Crawler tiene aproximadamente 20 hilos que leen simultáneamente desde el mismo sitio. ¿Esto podría estar causando un problema?

¿Cómo reduzco StreamReader.ReadToEnd veces DRÁSTICAMENTE?

Respuesta

8

WebClient's DownloadString es un contenedor simple para HttpWebRequest, ¿podría intentar usarlo temporalmente y ver si mejora la velocidad? Si las cosas se ponen mucho más rápido, ¿podría compartir su código para que podamos ver qué puede estar mal con él?

EDIT:

Parece HttpWebRequest observa configuración de IE 'max conexiones simultáneas', estas son las URLs en el mismo dominio? ¿Podría intentar aumentar el límite de conexiones para ver si eso ayuda? He encontrado this article sobre el problema:

Por defecto, no se puede realizar de manera más de 2-3 asincrónica HttpWebRequest (depende del sistema operativo). Con el fin de anularlo (la forma más fácil, en mi humilde opinión) no se olvide añadir esto bajo sección en la configuración archivo de la aplicación:

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

intentado usar cliente Web, mismos resultados (tiempos medios no han cambiado). Debo mencionar también que tengo una conexión de 1.5MBPS con una velocidad d/l promedio de 180KBPS Estaba pensando que tal vez 20 hilos que llamen a StreamReader.Read al mismo tiempo podrían tener algo que ver con eso? ¿O es esto irrelevante? – Roey

+0

En mi experiencia, en una conexión como esa saturarás el ancho de banda con 3-4 hilos. No es necesario ejecutar más a menos que los sitios web que está haciendo ping sean muy lentos y tenga hilos durmiendo mucho, esperando E/S. – kgriffs

+1

¡guau! Estaba usando async HttpWebRequest para cargar el servidor de prueba con aproximadamente 300 subprocesos por cliente y cada subproceso se estaba descargando "en serie". El cambio de la configuración de conexión máxima hizo que cada hilo descargara datos 10 veces más rápido. –

15

HttpWebRequest puede estar tomando un tiempo para detectar su proxy settings . Trate de añadir esto a su configuración de aplicación:

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

También puede ver un ligero aumento en el rendimiento de almacenamiento en búfer tus lecturas para reducir el número de llamadas realizadas a la toma de sistema operativo subyacente:

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

¡Gracias! ¡Eso aceleró totalmente mi código de segundos a milisegundos! –

+0

¿Cuál es el código equivalente en C++? El uso (...) no funciona en C++ – Edge

1

usted tiene probado ServicePointManager.maxConnections? Normalmente lo configuro en 200 para cosas similares a esto.

1

Tuve el mismo problema pero el peor. response = (HttpWebResponse) webRequest.GetResponse(); en mi código retrasó unos 10 segundos antes de ejecutar más código y después de esto la descarga saturó mi conexión. respuesta

de Kurt defaultProxy enabled = "false"

resuelto el problema.ahora la respuesta es casi instantánea y puedo descargar cualquier archivo http a mis conexiones velocidad máxima :) lo siento por mal inglés

1

Encontré que el método de configuración de la aplicación no funcionaba, pero el problema seguía siendo debido a la configuración del proxy. Mi petición simple que se usa para tomar hasta 30 segundos, ahora se necesita 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

que tenían el mismo problema, pero cuando me senté parámetro de proxy del HttpWebRequest a null, se resolvió el problema.

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

¡Gran solución! Funciona para mi. –

0

Gracias a todos por las respuestas, me han ayudado a cavar en la dirección correcta. Me he enfrentado con el mismo problema de rendimiento, aunque la solución para cambiar archivo de la aplicación de configuración (como se entendía que la solución es para aplicaciones web) no se ajusta a mis necesidades propuesto, mi solución es la siguiente:

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

Por qué ¿No resolvería este problema el multihilo? El multiproceso minimizaría los tiempos de espera de la red, y como almacenaría el contenido del búfer en la memoria del sistema (RAM), no habría un cuello de botella IO al tratar con un sistema de archivos. Por lo tanto, sus 82 páginas que tardan 82 segundos en descargarse y analizarse, deberían tomarse como 15 segundos (suponiendo un procesador 4x). Corrígeme si me falta algo.

____ DESCARGA DE HILO _____ *

descargar contenidos

formar la corriente

leer el contenido

_________________________ *

+0

El OP ya indica que se utilizan "aproximadamente 20" subprocesos. – Spooky