Nabushika
Nabushika

Reputation: 464

Async file download in VB not working

I have the following:

wc.DownloadDataCompleted += Wc_DownloadDataCompleted;
FileStream f = File.OpenWrite(insLoc + "\\update.zip");
wc.DownloadDataAsync(new Uri("http://example.com/file.zip"), installLoc + "\\file.zip");

(and in a separate function)

private void Wc_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
    {
        if (e.Error == null) {
            MessageBox.Show("Download success");
        }
        else { MessageBox.Show("Download failed"); }

        f.Flush();
        f.Dispose();
    }

When I check the file it is supposed to be downloading to, it exists, but there is nothing in it (ie, it is 0 bytes). I have flushed the FileStream after the download has finished, so what is happening? I have a progress bar as well, and it slowly increases to 100% so I know it's downloading the ZIP file, and the "Download Success" messagebox is shown.

Thanks in advance!

Upvotes: 1

Views: 125

Answers (2)

Eser
Eser

Reputation: 12546

I would use DownloadFileTaskAsync method of WebClient which I find very simple to use..

await wc.DownloadFileTaskAsync(new Uri("http://example.com/file.zip"), installLoc + "\\file.zip");

That is all. If you want to see the download progress, you can attach to DownloadProgressChanged event.

Upvotes: 1

Darin Dimitrov
Darin Dimitrov

Reputation: 1038800

You should use the callback function to save the resulting file (represented as a byte array passed as second argument):

wc.DownloadDataCompleted += Wc_DownloadDataCompleted;
wc.DownloadDataAsync(new Uri("http://example.com/file.zip"));

and then:

private void Wc_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
    if (e.Error == null) 
    {
        string resultFile = Path.Combine(insLoc, "update.zip");
        System.IO.File.WriteAllBytes(resultFile, e.Result);
        MessageBox.Show("Download success");
    }
    else 
    {
        MessageBox.Show("Download failed"); 
    }
}

Now you can quickly see that using this method the entire file is loaded in memory as a byte array before flushing it to the file system. This is hugely inefficient especially if you are downloading large files. For this reason it is recommended to use the DownloadFileAsync method instead.

wc.DownloadFileCompleted += Wc_DownloadFileCompleted;
string resultFile = Path.Combine(insLoc, "update.zip");
var uri = new Uri("http://example.com/file.zip");
wc.DownloadFileAsync(uri, resultFile);

and the corresponding callback:

private void Wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
    if (e.Error == null) 
    {
        MessageBox.Show("Download success");
    }
    else 
    { 
        MessageBox.Show("Download failed"); 
    }
}

Upvotes: 2

Related Questions