Quantcast
Channel: VBForums - Visual Basic .NET
Viewing all articles
Browse latest Browse all 27554

VS 2012 Help with cancelling webclient downloads

$
0
0
I'm working on a download manager and need the ability to cancel a specific download in progress. This issue I'm having is that CancelAsync doesn't accept any arguments and I can't seem to figure out how to cancel a certain download when multiple downloads are in progress - when I do click on a cancel button (DataGridViewButton) in the DataGridView - it cancels the last download that was started. I understand why that is, but I'm not yet able to find a way around it.

Code:

Imports System.Net
Imports System.IO
Imports System.ComponentModel
Imports System.Threading
Imports System.Collections.Concurrent

Public Class Form1

    Dim webClient As WebClient
    Dim url1 As String = "http://87.76.16.10/test100.zip"
    Dim url2 As String = "http://chicago.futurehosting.com/test100.zip"
    Dim url3 As String = "http://london.futurehosting.com/test100.zip"
    Dim url4 As String = "http://lax.futurehosting.com/test100.zip"
    Dim url5 As String = "http://mia.futurehosting.com/test100.zip"
    Dim path As String = Directory.GetCurrentDirectory()
    Const MaxClients As Integer = 4
    Dim ClientQueue As New BlockingCollection(Of WebClient)
    Dim UrlQueue As New Queue(Of String)()
    Dim downloadThread As Thread
    Dim url As String

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim ClientQueue As New BlockingCollection(Of WebClient)(MaxClients)

        DataGridView1.BackgroundColor = Color.White
        DataGridView1.RowHeadersVisible = False
        DataGridView1.AllowUserToAddRows = False

        Dim column1 As New DataGridViewTextBoxColumn()
        column1.HeaderText = "Current Downloads"
        column1.Name = "Column1"
        column1.Width = 215
        DataGridView1.Columns.Add(column1)

        Dim column2 As New DataGridViewTextBoxColumn()
        column2.HeaderText = "Percent Complete"
        column2.Name = "Column2"
        column2.Width = 100
        DataGridView1.Columns.Add(column2)

        Dim column3 As New DataGridViewButtonColumn()
        column3.HeaderText = ""
        column3.Name = "Column3"
        column3.Width = 100
        DataGridView1.Columns.Add(column3)
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        UrlQueue.Clear()

        While ClientQueue.Count > 0
            ClientQueue.TryTake(webclient)
        End While

        For i As Integer = 0 To MaxClients - 1
            Dim cli As New WebClient()
            AddHandler cli.DownloadFileCompleted, AddressOf DownloadFileCompleted
            AddHandler cli.DownloadProgressChanged, AddressOf DownloadProgressChanged
            ClientQueue.Add(cli)
        Next

        If CheckBox1.Checked = True Then
            UrlQueue.Enqueue(url1)
            CheckBox1.Checked = False
        End If

        If CheckBox2.Checked = True Then
            UrlQueue.Enqueue(url2)
            CheckBox2.Checked = False
        End If

        If CheckBox3.Checked = True Then
            UrlQueue.Enqueue(url3)
            CheckBox3.Checked = False
        End If

        If CheckBox4.Checked = True Then
            UrlQueue.Enqueue(url4)
            CheckBox4.Checked = False
        End If

        If CheckBox5.Checked = True Then
            UrlQueue.Enqueue(url5)
            CheckBox5.Checked = False
        End If


        downloadThread = New Thread(AddressOf downloadQueue)
        downloadThread.IsBackground = True
        downloadThread.Start()
    End Sub

    Public Sub downloadQueue()
        While UrlQueue.Count > 0
            webclient = ClientQueue.Take()
            Dim url As String = UrlQueue.Dequeue()
            Dim programInfo As Program = GetProgram(url)

            webclient.DownloadFileAsync(New Uri(url), programInfo.sFileName, New DownloadArgs(url, programInfo.sFileName, webclient))

            addValue(programInfo.programName)

        End While
    End Sub

    Public Sub addValue(text As String)

        If DataGridView1.InvokeRequired Then
            DataGridView1.Invoke(New Action(Of String)(AddressOf addValue), text)
            Exit Sub
        End If

        Dim n As Integer = DataGridView1.Rows.Add()
        DataGridView1.Rows.Item(n).Cells(0).Value = text
    End Sub

    Public Sub DownloadProgressChanged(sender As Object, e As DownloadProgressChangedEventArgs)
        Dim args As DownloadArgs = DirectCast(e.UserState, DownloadArgs)
        Dim url As String = args.Url
        Dim programInfo As Program = GetProgram(url)
        Dim programName As String = programInfo.programName

        Dim percent As String = e.ProgressPercentage.ToString

        For Rowindex = DataGridView1.Rows.Count - 1 To 0 Step -1
            If DataGridView1.Rows(Rowindex).Cells(0).Value = programName Then
                DataGridView1.Rows.Item(Rowindex).Cells(1).Value = percent
                DataGridView1.Rows.Item(Rowindex).Cells(2).Value = "Cancel"
            End If
        Next

    End Sub

    Public Sub DownloadFileCompleted(sender As Object, e As AsyncCompletedEventArgs)
        Dim args As DownloadArgs = DirectCast(e.UserState, DownloadArgs)
        Dim url As String = args.Url
        Dim programInfo As Program = GetProgram(url)
        Dim programName As String = programInfo.programName
        Dim savedName As String = programInfo.sFileName

        Dim file As New FileInfo(savedName)
        Dim sizeInBytes As Long = file.Length

        If e.Cancelled = True Then
            For Rowindex = DataGridView1.Rows.Count - 1 To 0 Step -1
                If DataGridView1.Rows(Rowindex).Cells(0).Value = programName Then
                    DataGridView1.Rows.Item(Rowindex).Cells(1).Value = "Cancelled"
                    DataGridView1.Rows.Item(Rowindex).Cells(2).Value = ""
                End If
            Next
        End If

        ClientQueue.Add(args.Client)
    End Sub

    'Handles click events for Cancel DataGridViewButtons
    Private Sub CellContentClick(ByVal sender As DataGridView, _
                ByVal e As DataGridViewCellEventArgs) _
                Handles DataGridView1.CellContentClick
        If e.RowIndex >= 0 AndAlso sender.Columns(e.ColumnIndex).GetType() = GetType(DataGridViewButtonColumn) Then
            If DataGridView1.Rows.Item(e.RowIndex).Cells(2).Value = "Cancel" Then
                webclient.CancelAsync()
                'webclient.Dispose()
            Else
                MessageBox.Show("This download has already been cancelled")
                'TODO: hide button - appears to require a wall of code, can't simply use DataGridView1.Rows.Item(e.RowIndex).Cells(2).Visible = False
            End If
           
        End If
    End Sub

    Public Structure Program
        Public sFileName As String
        Public programName As String
    End Structure

    Public Function GetProgram(ByVal url As String) As Program
        Dim prog As Program = Nothing
        prog.sFileName = vbNullString
        prog.programName = vbNullString

        If url = url1 Then
            prog.sFileName = path & "\file1.zip"
            prog.programName = "File 1"
        End If

        If url = url2 Then
            prog.sFileName = path & "\file2.zip"
            prog.programName = "File 2"
        End If

        If url = url3 Then
            prog.sFileName = path & "\file3.zip"
            prog.programName = "File 3"
        End If

        If url = url4 Then
            prog.sFileName = path & "\file4.zip"
            prog.programName = "File 4"
        End If

        If url = url5 Then
            prog.sFileName = path & "\file5.zip"
            prog.programName = "File 5"
        End If
        Return prog
    End Function
End Class

Public Class DownloadArgs
    Public ReadOnly Url As String
    Public ReadOnly Filename As String
    Public ReadOnly Client As WebClient
    Public Sub New(u As String, f As String, c As WebClient)
        Url = u
        Filename = f
        Client = c
    End Sub
End Class


Viewing all articles
Browse latest Browse all 27554

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>