none
Hacer mas rapida la descarga. RRS feed

  • Pregunta

  • Mi programa esta encargado de descargar mails, pero la verdad es que encuentro que la forma con la que las descarga se demora mucho:

    Que es lo que hago:

    Descargo con un networkstream lo que alcance a ver, luego paso los bytes a STREAM, el cual itero hasta que encuentre chars ' '. 

    Pero se demora un monton!

    agrego mi código ( No se si esta bien lo que estoy haciendo de agregar mi codigo, es primera vez que lo hago)

    (Edite las marcas de respuesta, por que se demora lo mismo)...
             while (true)
                {
                    byte[] dataaleer = new byte[1024];
                    if (ns.DataAvailable || begin)
                    {
                        int a = ns.Read(dataaleer, 0, 1024);
                        begin = false;
                    }
                    System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
    
                    string str = enc.GetString(dataaleer).Trim();
                    string strsinespacios = "";
                    char[] strchar = str.ToCharArray();
                    for (int j = 0; j < strchar.Length; j++)
                    {
                        if (!strchar[j].Equals('\0'))
                        {
    
                            strsinespacios += strchar[j];
                        }
                        else
                        {
                            break;
                        }
                    }
    
                    resp1 += strsinespacios;
                    if (!ns.DataAvailable)
                    {
                        return resp1;
                    }
    
    ns es el NetworkStream.
    En el caso de los mails, como puedo saber cuanto pesa un mail, relleno hasta que se pase o iguale la cifra que me dan.


    Alguna idea con respecto a esto. Ultimamente pense en hacer Threads, con varias conecciones simultaneas, pero no se... 

    Gracias, Gonzalo Díaz Harcha.
    jueves, 11 de junio de 2009 4:52

Respuestas

Todas las respuestas

  • hola,

    una consulta que protocolo usas para conectarte a los mail, POP3, o IMAP ?

    Lo que tampoco aclaras es que obtienes del mail, o sea solo su contenido, o algun attach para procesar ?


    Using POP3 with C# to download and parse your mail.


    Lo que no me suena que sea correcto el uso del networkstream.

    A POP3 Client in C# .NET


    saludos
    Leandro Tuttini

    Work: Iceberg Solutions
    Blog
    Buenos Aires
    Argentina
    jueves, 11 de junio de 2009 15:42
  • Claro, la intencion es descargar via POP3, o IMAP. 

    Y bueno, la verdad es que descarga muy lento, no se la verdad.

    Y claro, también la intencion es descargar todo el mail, su archivo adjunto. Si tengo un mail con un archivo de 4 megas.. por ejemlo se demoraria años yo creo.


    Gonzalo Díaz.
    jueves, 11 de junio de 2009 16:35
  • ninguno de los dos links que me diste me corren.

    Gonzalo Díaz Harcha
    jueves, 11 de junio de 2009 16:45
  • La concatenación del string caracter a caracter puede ser muy lenta, aunque no se si lo suficiente como para que sea tu cuello de botella.

    Probá lo siguiente:

    string strsinespacios = null;
    for (int j = 0; j < strchar.Length; j++)
    {
        if (strchar[j].Equals('\0'))
        {
            strsinespacios = strsinespacios.SubString(0, j);
            break;
        }
    }
    strsinespacios = strsinespacios ?? strchar;
    

    Saludos,
    Fernando.

    I always try to Keep it Sharp & simple.
    • Editado Fernando Nicolet jueves, 11 de junio de 2009 16:48 Corrección del código.
    jueves, 11 de junio de 2009 16:46
  • Revisé el código un poco mejor para ver que estaba haciendo. Creo que el siguiente mejora la performance significantemente. También podés probar con bloques más grandes: 2048, 4096 o 8192 (este último, por algún motivo es el más popular).

    StringBuilder resp1 = new StringBuilder();
    while (true)
    {
        byte[] dataaleer = new byte[1024];
        int leido = 0;
        if (ns.DataAvailable || begin)
        {
            leido = ns.Read(dataaleer, 0, 1024);
            begin = false;
        }
    
        int i = 0;
        while ((dataaleer[i] != 0) && (i < leido))
            i++;
    
        resp1.Append(Encoding.ASCII.GetString(dataaleer, 0, i));
        if (!ns.DataAvailable)
        {
            return resp1.ToString();
        }
    }

    No está probado, aunque si compila.
    Saludos y después contame como te fue.
    I always try to Keep it Sharp & simple.
    jueves, 11 de junio de 2009 17:38
  • Esta es la más popular dado que el uso de la clase StringBuilder en interaciones es mucho más eficiente que utilizando un string, por tal motivo tu cuello de botella era la cantidad de memoria que estabas gastando usando strings en cada iteracion. Saludos!
    Microsoft Certified Professional
    Profesionista Microsoft VIP México
    Blog Técnico
    World Wide Finalist Imagine Cup 2007
    Microsoft Student Partner
    C#, WPF, WCF
    LinkedIn
    jueves, 11 de junio de 2009 17:44
  • Me refería a la popularidad de bloques de 8192. Pero sin duda el uso del StringBuilder va a proporcionar mejor rendimiento, no sólo por el uso de memoria sino también por que la construcción del string se hace una sola vez. Antes en cada concatenación se estaba desechando el string anterior y armando uno nuevo (esto es debido a que los string en C# son inmutables).
    I always try to Keep it Sharp & simple.
    jueves, 11 de junio de 2009 17:50
  • Bueno hice algunos cmabios segun lo que me dijeron, pero igual se demora 30 seg en descargar 200kb...  muy poco pensando que los mails pueden agregar atachts de 10 mb, serían 28 MINUTOS!.  (Una idea que no se si será valida, por cada mail poner un thread, pero no se si sera valida, por la coneccion tcp, si es valida por favor me dicen)

    les agrego el metodo completo que me esta descargando:

            private string getemailtest2(int indexservidor)
            {
                StringBuilder resp1 = new StringBuilder();
                bool begin = true;
                //1 mas que 8192, el largo del buffer. 
                int compa = 8193;
                System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
                while (true)
                {
                    byte[] dataaleer = new byte[8192];
                    if (ns.DataAvailable || begin)
                    {
                        int a = ns.Read(dataaleer, 0, 8192);
                    }
                    resp1.Append(enc.GetString(dataaleer).Trim('\0'));
                    if (begin)
                    {
                        compa = Int32.Parse(resp1.ToString().Split(' ')[1]);
                        begin = false;
                    }
                    int leng = enc.GetBytes(resp1.ToString()).Length;
                    if (leng >= compa)
                    {
                        if (!ns.DataAvailable)
                        {
                            break;
                        }
                    }
    
                }
                return resp1.ToString();
    
            }

    viernes, 12 de junio de 2009 3:44
  • Hola Gonzalo. Me parece que esta altura lo más correcto es encontrar el problema "por descarte".

    Probá el siguiente código para ver cuando demora. Lo único que hace es bajar el mail, sin guardarlo ni nada y evaluar la velocidad:

    private void getemailtest2(int indexservidor)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        byte[] dataaleer = new byte[8192];
        bool begin = true;
        int bytesBajados = 0;
        while (true)
        {
            if (ns.DataAvailable || begin)
            {
                bytesBajados += ns.Read(dataaleer, 0, 8192);
            }
            if (!ns.DataAvailable)
            {
                break;
            }
        }
        sw.Stop();
        double tazaDeBajada = (bytesBajados / (double)sw.Elapsed.TotalSeconds) / 1024.0;
        Debug.WriteLine(string.Format("{0} KB bajados en {1} segundos.", bytesBajados / 1024, sw.Elapsed.TotalSeconds));
        Debug.WriteLine(string.Format("Velocidad: {0:0.00} KB/s", tazaDeBajada));
    }

    Probalo y contanos que resultados te dio.


    I always try to Keep it Sharp & simple.
    viernes, 12 de junio de 2009 15:13
  • como hago funcionar eso? :) o como lo veo?
    sábado, 13 de junio de 2009 2:33
  • Mi gran duda es como hacer que baje a mi velocidad real... 

    ejemplo.. que baje como si estuviera bajando algo de internet con mi explorador.. que me baja al rededor de 1mbps... :( ! esta es mi duda en general.. no se que hacer. 

    Como funcionan los gestores de descarga y esas cosas??? 

    Gonzalo Díaz. 
    sábado, 13 de junio de 2009 2:42
  • Hola de nuevo Gonzalo. Recién vi tu post en el foro Visual C# General ;)

    Volviendo al tema de la velocidad, el último código que te propuse solo baja los mails sin hacer ninguna operación extra. Eso te debería funcionar a tu velocidad real (siempre y cuando el servidor donde estan los mails lo soporte). Si sigue funcionando lento entonces ya no habría dudas de que el problema de velocidad no está en tu código sino en otro lado.

    Mientras voy a leer un poco sobre NetworkStream a ver si veo algo que pueda estar causando el problema.

    Saludos,
    Fernando.
    I always try to Keep it Sharp & simple.
    sábado, 13 de junio de 2009 14:35
  • cabe alguna posibilidad de que conversemos por gtalk, msn, facebook o algo asi, porfavor =)

    Gonzalo Díaz Harcha (go.diazh@gmail.com gtalk, counterhake_odisea@hotmail.com)
    sábado, 13 de junio de 2009 15:11
  • Te agregué al gtalk.

    I always try to Keep it Sharp & simple.
    • Marcado como respuesta Gonzalo Díaz lunes, 15 de junio de 2009 2:15
    sábado, 13 de junio de 2009 15:15