2011-08-08 26 views
11

Tengo un problema con Webclient.WebClient es muy lento

Es muy lento. La descarga de String de un sitio web tarda entre 3 y 5 segundos. No tengo ningún problema de red.

Esta es mi Modifed cliente Web.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Net; 

namespace StatusChecker 
{ 
    class WebClientEx: WebClient 
    { 
     public CookieContainer CookieContainer { get; private set; } 

     public WebClientEx() 
     { 
      CookieContainer = new CookieContainer(); 

      ServicePointManager.Expect100Continue = false; 
      Encoding = System.Text.Encoding.UTF8; 

      WebRequest.DefaultWebProxy = null; 
      Proxy = null; 
     } 

     public void ClearCookies() 
     { 
      CookieContainer = new CookieContainer(); 
     } 

     protected override WebRequest GetWebRequest(Uri address) 
     { 

      var request = base.GetWebRequest(address); 
      if (request is HttpWebRequest) 
      { 
       (request as HttpWebRequest).CookieContainer = CookieContainer; 
      } 
      return request; 
     } 
    } 
} 

ACTUALIZACIÓN: En Wireshark he visto que la única DownladString está enviando y recibiendo paquetes pocos miles.

+4

cliente Web no es especialmente lento, el problema debe estar en otra parte ... ¿Quizás el sitio web desde el que estás descargando es lento? –

+1

debería intentar usar un registrador de tráfico como Wireshark para determinar si el retraso es de hecho entre los marcos de petición y respuesta individuales (causadas por la red/desaceleración servidor) o que está ocurriendo debido a que el código de cliente se está portando mal y el envío de demasiadas peticiones o algo así la lógica error. –

+0

Ejecute también varias descargas en un bucle para "calentar" el proceso (elimine la carga de ensamblajes, por ejemplo). –

Respuesta

30

Puede haber dos temas en cuestión aquí (que también he notado en mis propios programas previamente):

  • La primera solicitud toma un tiempo anormalmente largo: Esto se debe a que WebRequest por defecto detecta y carga la configuración del proxy la primera vez que se inicia, lo que puede llevar bastante tiempo. Para detener esto, basta con establecer la propiedad proxy (WebRequest.Proxy) a null y va a omitir la comprobación (siempre se puede acceder directamente a la Internet)
  • No se puede descargar más de 2 artículos a la vez: Por defecto, solo puedes tener 2 conexiones HTTP simultáneas abiertas. Para cambiar esto, configure ServicePointManager.DefaultConnectionLimit en algo más grande. Por lo general, configuro esto en int.MaxValue (solo asegúrese de no enviar correo no deseado al host con 1,000,000 de conexiones).
+1

? Esta no es la respuesta correcta en mi caso. Puede ver que ya configuré el proxy como nulo. Y no descargo 2 elementos al mismo tiempo. Como también agregué a mi publicación que en Wireshark puedo ver que mi aplicación envía y recibe miles de paquetes por cada cadena de descarga. String es un sitio web simple como google.com. – Hooch

+0

Si no es anormalmente lento (lo que significa que las conexiones tienen aproximadamente la misma velocidad con keepalives desactivados), entonces está funcionando como debería. Lleva tiempo ejecutar el apretón de manos, realizar la solicitud, esperar a que el servidor cree una respuesta y luego leer la respuesta. – foxy

+0

¿Puede decirme un poco más sobre esos keep alives? ¿Y por qué mi aplicación envía miles de paquetes? – Hooch

0

Tal vez pueda ayudar a alguien. Algunos servicios web admiten compresión (gzip u otro). De modo que puede agregar el encabezado Aceptar codificación para sus solicitudes y luego habilitar automatic decompression para la instancia del cliente web. Chrome funciona de esa manera.

0

Hay algunas opciones si está relacionado con la configuración inicial del proxy siendo verificado:

  1. deshabilitar la configuración de detección automática de proxy en Internet Explorer
  2. Configure el proxy para nulo:

    WebClient.Proxy = null

  3. Al iniciarse la aplicación, establezca el webproxy predeterminado como nulo:

    WebRequest.DefaultWebProxy = null;

En el código .NET mayores en lugar de establecer en nulo, que utilizó para escribir esto (pero ahora es nula preferido):

webclient.Proxy = GlobalProxySelection.GetEmptyWebProxy();