none
Como limitar Velocidade de download ao baixar um arquivo? RRS feed

  • Pergunta

  • Ola, estou baixando alguns arquivos, a parte de baixar está Ok, mas agora preciso limitar a velocidade, mas estou com problema ao tentar fazer isto. Eu preciso da limitação pôs não quero "matar" minha internet.

    A última cosia que tentei foi:

    public static int BYTEDOWN { get; private set; }
        public static int MAX_SPEED { get; private set; } = 0;
    
        public static void HttpDownloadFile(string url, string path, int timeOut = 20000, string headers = "", long startByte = 0, long expectByte = -1)
        {
            // Speed
            System.Timers.Timer timer = new System.Timers.Timer(1000);   //Instantiate the Timer class
            timer.AutoReset = true;
            timer.Enabled = true;
            timer.Elapsed += delegate
            {
                Console.WriteLine("Speed: " + Global.FormatFileSize((BYTEDOWN)) + " / s"); // Convert To Mb | Kb.
                var spd = Global.FormatFileSize((BYTEDOWN));
                if (BYTEDOWN <= Global.STOP_SPEED * 1024)
                {
                    Console.WriteLine("Speed: " + Global.FormatFileSize((BYTEDOWN)) + " / s "); // Convert To Mb | Kb.
                }
                else
                {
                    BYTEDOWN = 0;
    
                }
            };
    
            // Downlaod
            try
            {
                if (File.Exists(path))
                    File.Delete(path);
    
                HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
                request.Timeout = timeOut;
                request.ReadWriteTimeout = timeOut; //important
                request.AllowAutoRedirect = true;
                request.KeepAlive = false;
                request.Method = "GET";
    
                long totalLen = 0;
                long downLen = 0;
                using (var response = (HttpWebResponse)request.GetResponse()) 
                {
                    using (var responseStream = response.GetResponseStream())
                    {
                        using (var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            //responseStream.CopyTo(stream);
                            totalLen = response.ContentLength;
                            byte[] bArr = new byte[1024];
                            int size = responseStream.Read(bArr, 0, (int)bArr.Length);
                            while (size > 0)
                            {
                                stream.Write(bArr, 0, size);
                                downLen += size;
                                BYTEDOWN += size; //Calculate download speed
                                if (MAX_SPEED != 0)
                                    while (BYTEDOWN >= MAX_SPEED * 1024 )  //Speed limit
                                    {
                                        Thread.Sleep(1);
                                    }
                                size = responseStream.Read(bArr, 0, (int)bArr.Length);
    
                            }
                        }
                    }
                }
    
                if (totalLen != -1 && downLen != totalLen)
                    try { File.Delete(path); } catch (Exception) { }
            }
            catch (Exception e)
            {
                try { File.Delete(path); } catch (Exception) { }
            }
    
            timer.Enabled = true;
    
        }

    Outra tentativa:

     while (size > 0)
                                {
                                    sw.Start();
    
                                    stream.Write(bArr, 0, size);
                                    downLen += size;
                                    BYTEDOWN += size; //Calculate download speed
                                    //if (MAX_SPEED != 0)
                                    //{
                                    //    while (BYTEDOWN >= MAX_SPEED * 1024)  //Speed limit
                                    //    {
                                    //        Thread.Sleep(1);
                                    //    }
                                    //}
    
                                    if(MAX_SPEED > 0)
                                    {
                                      if(BYTEDOWN >= MAX_SPEED * 1024)
                                        {
                                            while (sw.ElapsedMilliseconds <=1000)
                                            {
                                                Thread.Sleep(1);
                                            }
                                            sw.Reset();
                                        }
                                    }
    
                                    size = responseStream.Read(bArr, 0, (int)bArr.Length);
                                                                    
                                }



    • Editado _Lucas_-Pedro quinta-feira, 6 de fevereiro de 2020 20:30
    quarta-feira, 5 de fevereiro de 2020 21:31

Todas as Respostas

  • olá,

    mais ou menos seria  fazer o loop de leitura dentro do tickt do time, ele vai lendo e quando chegar a X byte por segundo ele para. ai depois ele volta de novo. Mas antes inicia os objetos numa variável global por exemplo

    quinta-feira, 6 de fevereiro de 2020 17:40
    Moderador
  • Ola, meio que é isso que faço, só que na hora do download em vez de um timer separado. Eu fiz uma nova versão que funciona parecido: Edição "Outra Tentativa".

    Resumindo o que eu faço é:

    1- Iniciar um timer

    2- Baixar até o limite estipulado

    3- Caso leve menos de 1s para chegar no limite, aguarde até dar 1s.

    4- Continua com o download

    Eu fiz alguns testes com a velocidade de download limitada e funcionou (calculei o tempo que demoraria para baixar o arquivo de tamanho x a y velocidade) o tempo chegou perto com uma margem de uns 20 a 40s, mas na hora de "imprimir" os resultados a velocidade sempre fica fixa no limite estipulado sem variação. Ex: Se eu limitar a 300KB/s o Console sempre mostra 300 embora o task manager mostre algumas alterações de velocidade.

    Por que isso acontece e da para resolver?



    • Editado _Lucas_-Pedro quinta-feira, 6 de fevereiro de 2020 21:17
    quinta-feira, 6 de fevereiro de 2020 21:16
  • essa do console ai terás que depurar para ver.

    olha esse projeto aqui, ele tem limitador de velocidade

    https://github.com/markodt/SGet

    sexta-feira, 7 de fevereiro de 2020 18:06
    Moderador
  • Ok, vou dar uma olhada nele.
    sábado, 8 de fevereiro de 2020 19:37