Question

I have a small app that downloads some files from a remote (HTTP) server to the users local hard drive, some of the files are large, but I don't know just how large at run time. Is there any method that will allow me download a file with some type of progress meter?

This is a WinForms app, right now I'm using WebClient.DownloadFile() to download the file.

Edit: I've looked into the DownloadProgressChanged and OnDownloadProgressChanged events and they seem to work fine, but they will not work for my solution. I am downloading several files and if I use WebClient.DownloadFileAsync then the event is called several times/second because each file calls it.
Here is the basic structure of the app:

  • Download a list of files typically about 114
  • Run a loop over the list of files and download each one to its desination

I don't mind downloading each file seperatly but without downloading them with DownloadFileAsync() I cannot use the event handlers.

Was it helpful?

Solution

Use WebClient.OnDownloadProgressChanged. Keep in mind, it's only possible to calculate progress if the server reports the size up front.

EDIT:

Looking at your update, what you can try is making a queue of URLs. Then, when a file finishes downloading (DownloadDataCompleted event), you will launch the async download of the next URL in the queue. I haven't tested this.

OTHER TIPS

Handle the WebClient DownloadProgressChanged event.

I've just written this and it definately appears to do what you want.

Also, within the ProgressChanged Event you've got the "TotalBytesToReceive" property and the "BytesReceived" property.

private void StartDownload()
{

    // Create a new WebClient instance.
    WebClient myWebClient = new WebClient();

    // Set the progress bar max to 100 for 100%
    progressBar1.Value = 0;
    progressBar1.Maximum = 100;

    // Assign the events to capture the progress percentage
    myWebClient.DownloadDataCompleted+=new DownloadDataCompletedEventHandler(myWebClient_DownloadDataCompleted);
    myWebClient.DownloadProgressChanged+=new DownloadProgressChangedEventHandler(myWebClient_DownloadProgressChanged);

    // Set the Uri to the file you wish to download and fire it off Async
    Uri uri = new Uri("http://external.ivirtualdocket.com/update.cab");
    myWebClient.DownloadFileAsync(uri, "C:\\Update.cab");

}

void myWebClient_DownloadProgressChanged(object sender, System.Net.DownloadProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
}

void myWebClient_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
    progressBar1.Value = progressBar1.Maximum;
}

I needed to solve a similar problem, and GenericTypeTea's code example did the trick; except that I discovered that the DownloadDataCompleted event is not fired when you call the DownloadFileAsync method. Instead, the DownloadFileCompleted event is raised.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top