Question how can i make 2 webclients in same form?

kris914g

New member
Joined
Jul 1, 2013
Messages
4
Programming Experience
Beginner
hey im trying to make 2 webclients in same form so i can make more than 1 download i im trying but i dont know what im doing wrong here is my code:


if wi say there are 3 checkboxes i want i you select all 3 checkboxes there come 3 downloads if you select 2 checkboxes there come 2 downloads and i you select 1 there come 1 download and a progressbar
and setstatus enabled for all downloads
VB.NET:
Imports System.Net
Imports System.IO
Imports System.Diagnostics
Public Class Form1

    Private WithEvents WC2 As WebClient
    Private WithEvents WC As WebClient
#Region "Download RateVariables"
    Private ChangeInAmount As Integer
    Private PreviousAmount As Integer
    Private NextCheck As DateTime
#End Region


    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        setstatus("0 kb", "0kb", "0%", "0kb/s")
        WC = New WebClient
        WC2 = New WebClient
    End Sub
    Private Sub setstatus(CurDownload As String, ByVal TotalDownload As String, ByVal Percentage As String, ByVal Rate As String)
        Label1.Text = "Downloaded : " & CurDownload
        Label2.Text = "Download Size : " & TotalDownload
        Label3.Text = "Rate : " & Rate
        Label4.Text = "Percentage : " & Percentage
    End Sub
    Public Function CalculateRate(ByVal Input As Integer) As String
        Return Processbytes(Input) & "/s"
    End Function

    Public Function Processbytes(ByVal Input As Integer) As String

        'Check if the file is 1GB or more
        If Input >= 1073741824 Then
            Return Math.Round(CDbl(Input / 1073741824), 2) & " GB"
        Else
            'Check for MB
            If Input >= 1048576 Then
                Return Math.Round(CDbl(Input / 1048576), 2) & " MB"
            Else
                'Can only be in KB
                Return Math.Round(CDbl(Input / 1024), 2) & " KB"
            End If

        End If

    End Function

    Private Function CDb1(p1 As Double) As Double
        Throw New NotImplementedException
    End Function

    Private Sub WC_DownloadFileCompleted(sender As Object, e As System.ComponentModel.AsyncCompletedEventArgs) Handles WC.DownloadFileCompleted
        ProgressBar1.Value = 0
        ProgressBar1.Maximum = 0
        ChangeInAmount = 0
        PreviousAmount = 0
        NextCheck = Now.AddSeconds(1)
    End Sub

    Private Sub WC2_DownloadFileCompleted(sender As Object, e As System.ComponentModel.AsyncCompletedEventArgs) Handles WC.DownloadFileCompleted
        ProgressBar1.Value = 0
        ProgressBar1.Maximum = 0
        ChangeInAmount = 0
        PreviousAmount = 0
        NextCheck = Now.AddSeconds(1)
    End Sub

    Private Sub WC_DownloadProgressChanged(sender As Object, e As DownloadProgressChangedEventArgs) Handles WC.DownloadProgressChanged
        Try
            If Now > NextCheck Then
                ChangeInAmount = e.BytesReceived - PreviousAmount
                PreviousAmount = e.BytesReceived
                NextCheck.AddSeconds(1)
            End If
            Dim Rate As String = CalculateRate(ChangeInAmount)
            ProgressBar1.Maximum = e.TotalBytesToReceive
            ProgressBar1.Value = e.BytesReceived
            setstatus(Processbytes(e.BytesReceived), Processbytes(e.TotalBytesToReceive), e.ProgressPercentage, Rate)
        Catch
        End Try
    End Sub


    Private Sub WC2_DownloadProgressChanged(sender As Object, e As DownloadProgressChangedEventArgs) Handles WC.DownloadProgressChanged
        Try
            If Now > NextCheck Then
                ChangeInAmount = e.BytesReceived - PreviousAmount
                PreviousAmount = e.BytesReceived
                NextCheck.AddSeconds(1)
            End If
            Dim Rate As String = CalculateRate(ChangeInAmount)
            ProgressBar1.Maximum = e.TotalBytesToReceive
            ProgressBar1.Value = e.BytesReceived
            setstatus(Processbytes(e.BytesReceived), Processbytes(e.TotalBytesToReceive), e.ProgressPercentage, Rate)
        Catch
        End Try
    End Sub

   
    

   
    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click

        If CheckBox1.Checked = True Then

            Dim webAddress As String = "https://dl.dropboxusercontent.com/u/185853590/download%20Manager/Update/Tool%20update.txt"
            Dim SFD As New SaveFileDialog
            If SFD.ShowDialog() = DialogResult.OK Then
                WC.DownloadFileAsync(New Uri("https://dl.dropboxusercontent.com/u/185853590/download%20Manager/Update/Tool%20update.txt"), SFD.FileName)
            End If

        End If

        If CheckBox2.Checked = True Then

            Dim webAddress2 As String = "https://dl.dropboxusercontent.com/u/185853590/download%20Manager/Update/Tool%20update.txt"
            Dim SFD As New SaveFileDialog
            If SFD.ShowDialog() = DialogResult.OK Then
                WC2.DownloadFileAsync(New Uri("https://dl.dropboxusercontent.com/u/185853590/download%20Manager/Update/Tool%20update.txt"), SFD.FileName)
            End If

        End If

    End Sub
End Class
 
Last edited:
If you want to perform three downloads then obviously two WebClients is inadequate. Don't use member variables at all. When it comes time to perform the downloads, create exactly as many WebClient objects as you need then and there. You can use AddHandler to attach the event handlers and access the appropriate WebClient object via the 'sender' parameter in each event handler. You would use RemoveHandler and call Dispose when you're done, e.g.
Private Sub DownloadFile(source As String, destination As String)
    Dim client As New WebClient

    AddHandler client.DownloadProgressChanged, AddressOf WebClient_DownloadProgressChanged
    AddHandler client.DownloadFileCompleted, AddressOf WebClient_DownloadFileCompleted

    client.DownloadFileAsync(New Uri(source), destination)
End Sub

Private Sub WebClient_DownloadProgressChanged(sender As Object, e As DownloadProgressChangedEventArgs)
    Dim client = DirectCast(sender, WebClient)

    '...
End Sub

Private Sub WebClient_DownloadFileCompleted(sender As Object, e As AsyncCompletedEventArgs)
    Dim client = DirectCast(sender, WebClient)

    RemoveHandler client.DownloadProgressChanged, AddressOf WebClient_DownloadProgressChanged
    RemoveHandler client.DownloadFileCompleted, AddressOf WebClient_DownloadFileCompleted

    client.Dispose()

    '...
End Sub
You can simply call that DownloadFile method as many times as you like.
 
I want it so that If you have 10 checkboxes, so if you have selected four check boxes so you get 4 files where the progress bar and SetStatus fits all download and downloadsne come one at a time

pls can you edit my code so it pass to my description?
 
I'm not editing your code so let's make that the last time you ask for that. If you're only doing one download at a time then you only need one WebClient. Call its DownloadFileAsync for the first URL and then, when it raises its DownloadFileCompleted event, call it again for the next URL. You can use an array or collection and an index to store the URLs and determine which one to use or, if you want to get a little bit fancier, use a Queue.
 
i have searched for it but could not find something i know you dont want to edit my code but pls can you make a example for it (not with my code), with 3 downloads with one file at a time with Queue so i can se it becus i dont know the code?
 
If you can't find an example that uses a Queue then you haven't looked. As for how to use it in this case, you would call Enqueue to add each item and call Dequeue each time you want to use an item. You want to use an item before you call DownloadFileAsync each time, which you will do once in a Button's Click event handler or the like and then in the DownloadFileCompleted event handler. Make sure that you test the Count first and, if it's zero, there are no more items to download.

So, the first step is to create the Queue, or preferably a Queue(Of String) if you're storing Strings containing URLs, and enqueue all the items. If you can't do that then you can't do anything else so forget everything else for the moment and just concentrate on that. The obvious first step when using a new type or member should be to read the documentation for that type or member. That's what the Help menu is in your IDE for. Read the documentation for the Queue(Of T) class to get a description of the class, a list of members and their descriptions and probably some code examples too.

Once you've read that documentation and searched for other information and examples on the web if you need them, then you can try to write code to just create the Queue. If you have issues then post just that code and tell us what happened. Then we can address just that issue. Once you can create the Queue, then you can think about using it. This is how software development works: break a problem up and solve each part in isolation, then put all the bits together and you have inherently solved the original problem.

Note that a Queue(Of T) is to a Queue as a List(Of T) is to an ArrayList, i.e. they do the same job but one is generic and one isn't. You should pretty much always use the generic option if there is one.
 
Back
Top