Daniel Shields
Daniel Shields

Reputation: 13

Downloading multiple files async VB.net

I am creating an installer/updater for the mods on my Minecraft server. I have it set it up so that there are two files, one mod per line, and the code compares the two and downloads the latest mod if they don't match. Currently I have the downloads setup like this:

        For x = 2 To latestModCount - 1
            If currentModList(x) <> latestModList(x) Then
                IO.File.Delete(applicationLocation & "multimc\instances\Dan's Server\minecraft\mods\" & currentModList(x))
                My.Computer.Network.DownloadFile(OnlineFiles & "mods/" & latestModList(x), _
                        applicationLocation & "multimc\instances\Dan's Server\minecraft\mods\" & latestModList(x))
            End If

            'Updates currentModList to = latestModList
            objWriter.Write(latestModList(x))
        Next

With this method the form completely freezes while the files are downloading.

What I want is to have a progress bar move along as each one downloads, resetting to zero each time a new one is complete. I know that using this method I can get one file to download and the progress bar will move along nicely. The problem with this though, is that because it uses an asynchronous download, any code below the above code is executed before the downloads have finished, which becomes a problem when trying to unzip a zip file that doesn't exist.

If someone has a solution, please provide code examples as I this is actually my first program in any language, other than tutorial ones.

Upvotes: 1

Views: 3795

Answers (1)

Player
Player

Reputation: 61

use WebClient.DownloadFileAsync and handle the completed download in client_DownloadCompleted.

Pseudo code:

Private i as Integer = -1

Private Sub StartNextDownload()
    Do
        i++
    Loop Until currentModList(i) <> latestModList(i)
    If i < latestModCount Then
        IO.File.Delete(applicationLocation & "multimc\instances\Dan's Server\minecraft\mods\" & currentModList(i))
        Dim client As WebClient = New WebClient
        AddHandler client.DownloadProgressChanged, AddressOf client_ProgressChanged
        AddHandler client.DownloadFileCompleted, AddressOf client_DownloadCompleted
        client.DownloadFileAsync(New Uri(OnlineFiles & "mods/" & latestModList(i)), applicationLocation & "multimc\instances\Dan's Server\minecraft\mods\" & latestModList(i))
    End If
End Sub

Private Sub client_ProgressChanged(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs)
    Dim bytesIn As Double = Double.Parse(e.BytesReceived.ToString())
    Dim totalBytes As Double = Double.Parse(e.TotalBytesToReceive.ToString())
    Dim percentage As Double = bytesIn / totalBytes * 100
    progressBar.Value = Int32.Parse(Math.Truncate(percentage).ToString())
End Sub

Private Sub client_DownloadCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs)
    HandleCompletedDownload() 'unzip and other stuffs there
    StartNextDownload()
End Sub

Another approach is to fire all downloads at once, similar to what you currently have (again, handle the completed download in client_DownloadCompleted). However in this approach you either use no progress bar at all, or do some beginner-unfriendly programming to track progress of individual/total downloads.

Upvotes: 0

Related Questions