1

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.

  • Try a [Background worker](http://stackoverflow.com/q/27565851/1070452) for the downloads - it can report the progress and not lock up the UI – Ňɏssa Pøngjǣrdenlarp Feb 07 '15 at 13:24
  • Async is a pretty advanced topic for a beginner. I would suggest you spend some time reading about this https://msdn.microsoft.com/en-us/library/jj152938%28v=vs.110%29.aspx – rory.ap Feb 07 '15 at 13:25
  • 1
    possible duplicate of [Download multiple files in parallel using c#](http://stackoverflow.com/questions/22747645/download-multiple-files-in-parallel-using-c-sharp) – Abdullah Saleem Feb 07 '15 at 13:33
  • http://stackoverflow.com/questions/22747645/download-multiple-files-in-parallel-using-c-sharp/22748172 – Abdullah Saleem Feb 07 '15 at 13:33
  • @Plutonix Thankyou for your contribution, however would you be able to post some code on how I can incorporate the background worker into my existing code. Like I said I am pretty new so thankyou for your patience. – Daniel Shields Feb 07 '15 at 19:29

1 Answers1

0

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.

Player
  • 61
  • 4
  • Thanks for the response. However I still don't understand how I can do this with, for example, a for loop. Could you place this code into my code? What I ultimately want is for the user to notified that the files are being downloaded, preferably without the GUI locking up. – Daniel Shields Feb 09 '15 at 18:01
  • @DanielShields edited my code. Call StartNextDownload to start. I don't have visual studio right now and some things depend on your own code, so don't expect it to work just by copypasting. – Player Feb 10 '15 at 15:07