1

I am learning how to use http requests and webclient in C# windows forms. Currently I have gotten the following code from Example and I am trying to make it work as well as understand it.

The code executes successfully and displays the messagebox "Download Complete" box but it does not actually download the file. Would someone explain to me how this works and what I am doing wrong?

    private void btnDownload_Click(object sender, EventArgs e)
    {
        string filepath = txtBxSaveTo.Text.ToString();
        WebClient webClient = new WebClient();
        webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
        webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
        webClient.DownloadFileAsync(new Uri("http://download.thinkbroadband.com/10MB.zip"), filepath);
    }

    private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        progressBar.Value = e.ProgressPercentage;
    }

    private void Completed(object sender, AsyncCompletedEventArgs e)
    {
        MessageBox.Show("Download completed!");
    }

    private void btnSavetoLocation_Click(object sender, EventArgs e)
    {
        FolderBrowserDialog selectedFolder = new FolderBrowserDialog();

        if (selectedFolder.ShowDialog() == DialogResult.OK)
        {
            txtBxSaveTo.Text = selectedFolder.SelectedPath;

        }
    }
}

}

Community
  • 1
  • 1
Kevin Farris
  • 11
  • 1
  • 1
  • 3
  • 1
    In your `Completed` handler, try checking `e.Error` and `e.Cancelled` https://msdn.microsoft.com/en-us/library/system.componentmodel.asynccompletedeventargs(v=vs.110).aspx – Jason P May 12 '15 at 19:38

2 Answers2

7

For this case, if you just want to download the file, you may want to make a Synchronously download call instead of an Asynchronously call like you are trying to implement.

This can be done in a manner similar to this:

private void btnDownload_Click(object sender, EventArgs e)
{
    string filepath = txtBxSaveTo.Text.ToString();
    WebClient webClient = new WebClient();
    webClient.DownloadFile("http://download.thinkbroadband.com/10MB.zip", filepath);
}

This will lock the program until the file is downloaded or an error occurs, but do you have a particular need to do this download Asynchronously? If you do then the following explanation might be of some use:

private void btnDownload_Click(object sender, EventArgs e)
{
  //Retrieve the path from the input textbox
  string filepath = txtBxSaveTo.Text.ToString();

  //Create a WebClient to use as our download proxy for the program.
  WebClient webClient = new WebClient();

  //Attach the DownloadFileCompleted event to your new AsyncCompletedEventHandler Completed
  //so when the event occurs the method is called.
  webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);

  //Attach the DownloadProgressChanged event to your DownloadProgressChangedEventHandler ProgressChanged,
  //so again when the event occurs the method is called.
  webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);

  //Attempt to actually download the file, this is where the error that you
  //won't see is probably occurring, this is because it checks the url in 
  //the blocking function internally and won't execute the download itself 
  //until this clears.
  webClient.DownloadFileAsync(new Uri("http://example.com/myfile.txt"), filepath);
}

//Method that just increments the progressBar every time the DownloadProgressChangedEvent from webClient fires.
private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
  progressBar.Value = e.ProgressPercentage;
}

//This is your method that will pop when the AsyncCompletedEvent is fired,
//this doesn't mean that the download was successful though which is why
//it's misleading, it just means that the Async process completed.
private void Completed(object sender, AsyncCompletedEventArgs e)
{
  MessageBox.Show("Download completed!");
}

Personally I would use a Synchronous call in this case until you get a better understand of Asynchronous calls and the pros and cons between them.

  • I was still having problems getting this to work until I placed a filename in the filepath string. Is there a method that can be used that will have the downloaded file automatically named the same as the file on the server? – Kevin Farris May 20 '15 at 17:22
  • Is there a reason you can't annotate the filename in such a manner as: `txtBxSaveTo.Text.ToString() + "10MB.zip"`? I'm curious since you seemed to be hardcoding the path to the file on server. – Noah Castro-Hart -GaelicGamer- May 21 '15 at 18:55
  • Not that I'm aware of, it just didn't seem prudent to include that in the example as that doesn't seem relevant to the original question. – Noah Castro-Hart -GaelicGamer- Apr 24 '20 at 15:07
0

The download file method is throwing an exception. Also ... use the non-async versions to start out with before going to async.

{"The remote server returned an error: (407) Proxy Authentication Required."}

Marc Johnston
  • 1,276
  • 1
  • 7
  • 16