1

The button click event for starting the download

private void btnStart_Click(object sender, EventArgs e)
        {
            downloadFile(links);           
        }

links is a List with some http links inside.

And the WebClient events

private void downloadFile(IEnumerable<string> urls)
        {
            foreach (var url in urls)
            {
                _downloadUrls.Enqueue(url);
            }

            // Starts the download
            btnStart.Text = "Downloading...";
            btnStart.Enabled = false;
            pBarFileProgress.Visible = true;

            DownloadFile();

            label2.Visible = true;
            label3.Visible = true;
            label4.Visible = true;
            label7.Visible = true;
            label3.Text = "";
            label7.Text = "";
            label2.Text = "";
            label4.Text = "";
        }

        private void DownloadFile()
        {
            if (_downloadUrls.Any())
            {
                client.DownloadProgressChanged += client_DownloadProgressChanged;
                client.DownloadFileCompleted += client_DownloadFileCompleted;

                url = _downloadUrls.Dequeue();

                if (url.Contains("animated") && url.Contains("infra"))
                {
                    string startTag = "animated/";
                    string endTag = "/infra";

                    int index = url.IndexOf(startTag);
                    int index1 = url.IndexOf(endTag);

                    fname = url.Substring(index + 9, index1 - index - 9);
                    var countryName = codeToFullNameMap[fname];
                    downloadDirectory = tbxMainDownloadPath.Text;
                    downloadDirectory = Path.Combine(downloadDirectory, countryName);
                }
                else
                {
                    fname = "Tempfile";
                    downloadDirectory = tbxMainDownloadPath.Text;
                }

                client.DownloadFileAsync(new Uri(url), downloadDirectory + "\\" + fname + ".gif", url);
                lastDownloadedFile = downloadDirectory + "\\" + fname + ".gif";

                return;
            }

            // End of the download
            label2.Text = "All files have been downloaded";
        }

        private void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                tracker.NewFile();
                DownloadFile();
                return;
                // handle cancelled scenario
            }
            if (e.Error != null)
            {
                // handle error scenario
                throw e.Error;
            }

            label2.Text = "Download Complete";

            string lastUrl = (string)e.UserState;

            listView1.BeginUpdate();
            foreach (ListViewItem li in listView1.Items)
            {
                if (li.SubItems[2].Text == lastUrl)
                {
                    li.SubItems[0].Text = "Downloaded";
                    li.SubItems.Add("Color");
                    li.SubItems[0].ForeColor = Color.Green;
                    li.UseItemStyleForSubItems = false;
                }
            }
            listView1.EndUpdate();

            tracker.NewFile();
            DownloadFile();
        }

        void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            tracker.SetProgress(e.BytesReceived, e.TotalBytesToReceive);
            pBarFileProgress.Value = (int)(tracker.GetProgress() * 100.0);
            label3.Text = e.BytesReceived + "/" + e.TotalBytesToReceive;
            label7.Text = tracker.GetBytesPerSecondString();
            label2.Text = "Downloading";
            label4.Text = downloadDirectory + "\\" + fname + ".gif";
        }

The exception is on line number 178

client.DownloadFileAsync(new Uri(url), downloadDirectory + "\\" + fname + ".gif", url);

And line 233 is in the completed event:

DownloadFile();

I tried to google in many answers it say that the download is not completed yet before running a new webclient request. I was sure if it's getting to the completed event that' mean the current download is finished no ?

How should i solve and handle this exception ?

The exception:

Blockquote InnerException: HResult=-2146233067 Message=WebClient does not support concurrent I/O operations. Source=System StackTrace: at System.Net.WebClient.ClearWebClientState() at System.Net.WebClient.DownloadFileAsync(Uri address, String fileName, Object userToken) at DownloadMultipleFiles.Form1.DownloadFile() in Form1.cs:line 178 at DownloadMultipleFiles.Form1.client_DownloadFileCompleted(Object sender, AsyncCompletedEventArgs e) in Form1.cs:line 233 at System.ComponentModel.AsyncCompletedEventHandler.Invoke(Object sender, AsyncCompletedEventArgs e) at System.Net.WebClient.OnDownloadFileCompleted(AsyncCompletedEventArgs e) at System.Net.WebClient.DownloadFileOperationCompleted(Object arg) InnerException:

Daniel Halfoni
  • 487
  • 10
  • 30
  • 1
    Possible duplicate of [WebClient multi file Downloader error](https://stackoverflow.com/questions/7675869/webclient-multi-file-downloader-error) or [How do I Async download multiple files using webclient, but one at a time?](https://stackoverflow.com/questions/6992553/how-do-i-async-download-multiple-files-using-webclient-but-one-at-a-time) – Mogsdad Jan 16 '18 at 03:11

1 Answers1

1

call the wait Methode of

client.DownloadFileAsync(new Uri(url), downloadDirectory + "\\" + fname + ".gif", url).Wait();

Have a try

DotNetDev
  • 205
  • 1
  • 10
  • How is this the accepted answer? This is essentially the same as `DownloadFile`, you're losing async capability because it blocks the thread. – JohanP Mar 16 '17 at 21:04
  • Like described unser https://msdn.microsoft.com/de-de/library/dd235635(v=vs.110).aspx you're right. Nethertheless it's a way to solve his issue. Another option would be to add a whil(true) loop , Or to be correct and await the stuff – DotNetDev Mar 17 '17 at 07:10
  • It is not the correct way to solve the issue at all. If the download is big, it will block the thread for ages until the entire download is finished. With the while loop inside DownloadCompleted, it will be a quick block only until !webclient.Isbusy. Awaiting the task will have the same issue because webclient could still be busy even after download has completed, hence why op has asked this question. – JohanP Mar 17 '17 at 11:10