Httpwebrequest.Getresponseasync is limiting to 2 simultaneous calls

Asked

Viewed 65 times

1

I own an application where clients can download packages that are files . zip with an average of 1Gb.

When starting a download, a new thread is created that will make the request and via stream rescues part of the bytes and goes writing in a file.

The problem is:

I start the first download and it works correctly.

I start the second and also works correctly, the two downloads run simultaneously.

But when I start the third one, the execution of the new thread stops waiting for the answer in the Getresponseasync() command (LINE 35), if I pause any of the previous downloads then yes the code continues, probably because one of the Webresponse instances that Getresponseasync returned is closed.

I need to be able to download several packages at the same time.

The method responsible for the download:

    private async void DownloadPackage()
    {
        FileStream fileStream = null;

        try
        {
            string appDataPath = GetAppDataPath();
            int currentIndex = 0;
            int bytesReceived = 0;
            int currentRateBytes = 0;
            long bytesSaved = 0;

            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(new Uri(GetPackageUrl()));

            if (File.Exists(appDataPath))
            {
                FileInfo fileInfo = new FileInfo(appDataPath);
                fileStream = File.Open(appDataPath, FileMode.Append);
                bytesSaved = fileInfo.Length;
                req.AddRange(bytesSaved);
            }
            else if (File.Exists(GetZipPackagePath()))
            {
                if (Directory.Exists(appDataPath))
                    Directory.Delete(appDataPath, true);

                File.Move(GetZipPackagePath(), appDataPath);
                PreparePresentation();
                DownloadCompleted();
                return;
            }
            else
                fileStream = File.Create(appDataPath);

            using (WebResponse response = await req.GetResponseAsync().ConfigureAwait(false))
            {
                long contentLength = response.ContentLength;

                using (Stream responseStream = response.GetResponseStream())
                {
                    DateTime lastRateUpdate = DateTime.Now;
                    byte[] buffer = new byte[2560];

                    while (currentIndex < contentLength)
                    {
                        if (!continueDownload)
                        {
                            DownloadPaused();
                            break;
                        }

                        try
                        {
                            bytesReceived = responseStream.Read(buffer, 0, 2560);
                            currentRateBytes += bytesReceived;
                            fileStream.Write(buffer, 0, bytesReceived);
                            fileStream.Flush();
                            currentIndex += bytesReceived;
                        }
                        catch (Exception e)
                        {
                            if (tryCount == 5)
                            {
                                string msg = string.Format("Ocorreu um erro ao tentar fazer download do pacote, verifique sua conexão e tente novamente.\nErro: {0}", e.Message);
                                MessageBox.Show(msg);
                                tryCount = 0;
                                continueDownload = false;
                                this.Invoke((MethodInvoker)delegate
                                {
                                    NeedDownload();
                                });
                                break;
                            }
                            else
                            {
                                tryCount++;
                                fileStream.Close();
                                response.Close();
                                DownloadPackage(new object(), new EventArgs());
                                return;
                            }
                        }
                        DateTime endTime = DateTime.Now;

                        if ((DateTime.Now - lastRateUpdate).TotalSeconds >= 2)
                        {
                            DownloadRate rate = CalculateRate(lastRateUpdate, endTime, currentIndex, contentLength, currentRateBytes);
                            double percentage = (double)(currentIndex + bytesSaved) / (contentLength + bytesSaved);
                            UpdateProgressBar((int)(percentage * 100), rate);
                            lastRateUpdate = DateTime.Now;
                            currentRateBytes = 0;
                        }
                    }
                    fileStream.Close();
                }

                response.Close();

                if (continueDownload && PreparePresentation())
                    DownloadCompleted();

            }
        }
        catch (Exception e)
        {
            string msg;
            if(fileStream != null) fileStream.Close();

            if (e is WebException && ((HttpWebResponse)((WebException)e).Response).StatusCode == HttpStatusCode.RequestedRangeNotSatisfiable)
            {
                try 
                {
                    if(PreparePresentation()) DownloadCompleted();
                    return;
                }
                catch (Exception ex)
                {
                    msg = string.Format("Ocorreu um erro ao finalizar pacote.\nErro: {0}", e.StackTrace);
                    MessageBox.Show(msg, e.Message);
                    this.Invoke((MethodInvoker)delegate
                    {
                        NeedDownload();
                    });
                    return;
                }
            }

            msg = string.Format("Ocorreu um erro ao tentar fazer download do pacote, verifique sua conexão e tente novamente.\nErro: {0}", e.Message);
            MessageBox.Show(msg, "Erro");
            this.Invoke((MethodInvoker)delegate
            {
                NeedDownload();
            });
        }
    }

Method call:

    private void DownloadPackage(object sender, EventArgs e)
    {
        //algumas verificações
        ThreadStart ts = new ThreadStart(DownloadPackage);
        new Thread(ts).Start();
    }

Note: These methods are within a Usercontrol for each available package. In this Usercontrol have buttons (to start and pause the download), progress bar, images, etc.

1 answer

1


You can use the property ServicePointManager.DefaultConnectionLimit to limit the connections outbound which you can do in your process. If you increase this value. The default value is 2, which explains what you are observing.

  • Perfect guy, it worked. Thanks for the help.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.