HttpWebRequest.GetResponseAsync is limiting to 2 simultaneous calls

1

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

When starting a download, a new thread is created that will make the request and via stream retrieves part of the bytes and writes to a file.

The problem is:

Start the first download and work correctly.

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

But when I start the third, the execution of the new thread is stopped waiting for the response in the command GetResponseAsync () (LINE 35), if I pause any of the previous downloads, yes, the code continues, probably because one of the WebResponse instances GetResponseAsync returned is closed.

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

The method responsible for downloading:

    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 inside a UserControl for each available package. In that UserControl have buttons (to start and pause the download), progress bar, images, etc.

    
asked by anonymous 17.03.2016 / 20:15

1 answer

1

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

    
17.03.2016 / 20:32