Results 1 to 5 of 5

Thread: [vb.net] How to use a progress bar while downloading through HttpClient

  1. #1

    Thread Starter
    Member
    Join Date
    Jul 2013
    Posts
    49

    [vb.net] How to use a progress bar while downloading through HttpClient

    Hi everybody,
    I want to use an async progress bar that show the download progress. I'm trying to do it using Progress <T> class.
    I've been trying a lots of codes but none of them is really async and the progress bar is really never being updated during download.
    My code is:
    Code:
    Private downloader As MyDownloader = Nothing
    
    Private Sub btnStartDownload_Click(sender As Object, e As EventArgs) Handles btnStartDownload.Click
        Dim progress = New Progress(Of String)(
            Sub(data)
                ' We're on the UI Thread here
                ListBox1.Items.Clear()
                ListBox1.Items.AddRange(Split(data, vbLf))
                RichTextBox1.SelectionStart = RichTextBox1.TextLength
            End Sub)
    
        Dim url As Uri = New Uri("https://SomeAddress.com")
        downloader = New MyDownloader()
        ' Download from url every 1 second and report back to the progress delegate
        downloader.StartDownload(progress, url, 1)
    
    Private Async Sub btnStopDownload_Click(sender As Object, e As EventArgs) Handles btnStopDownload.Click
        Await downloader.StopDownload()
    End Sub
    The helper class:

    Code:
    Imports System.Diagnostics
    Imports System.Net
    Imports System.Net.Http
    Imports System.Text.RegularExpressions
    
    Public Class MyDownloader
        Private Shared ReadOnly client As New HttpClient()
        Private ReadOnly cts As CancellationTokenSource = New CancellationTokenSource()
        Private interval As Integer = 0
    
        Public Sub StartDownload(progress As IProgress(Of String), url As Uri, intervalSeconds As Integer)
            interval = intervalSeconds * 1000
            Task.Run(Function() DownloadAsync(progress, url, cts.Token))
        End Sub
    
        Private Async Function DownloadAsync(progress As IProgress(Of String), url As Uri, token As CancellationToken) As Task
            Dim pattern As String = "<(?:[^>=]|='[^']*'|=""[^""]*""|=[^'""][^\s>]*)*>"
            Dim downloadTimeWatch As Stopwatch = New Stopwatch()
            downloadTimeWatch.Start()
            Do
                If cts.IsCancellationRequested Then Return
                Try
                    Dim response = Await client.GetAsync(url, HttpCompletionOption.ResponseContentRead, token)
                    Dim data = Await response.Content.ReadAsStringAsync()
    
                    data = WebUtility.HtmlDecode(Regex.Replace(data, pattern, ""))
                    progress.Report(data)
    
                    Dim delay = interval - CInt(downloadTimeWatch.ElapsedMilliseconds)
                    Await Task.Delay(If(delay <= 0, 10, delay), token)
                    downloadTimeWatch.Restart()
                Catch tcEx As TaskCanceledException
                    ' Don't care - catch a cancellation request
                    Debug.Print(tcEx.Message)
                Catch wEx As WebException
                    ' Internet connection failed? Internal server error? See what to do
                    Debug.Print(wEx.Message)
                End Try
            Loop
        End Function
    
        Public Async Function StopDownload() As Task
            Try
                cts.Cancel()
                client?.CancelPendingRequests()
                Await Task.Delay(interval)
            Finally
                client?.Dispose()
                cts?.Dispose()
            End Try
        End Function
    End Class
    Any idea? Thanks

  2. #2
    Karen Payne MVP kareninstructor's Avatar
    Join Date
    Jun 2008
    Location
    Oregon
    Posts
    6,541

    Re: [vb.net] How to use a progress bar while downloading through HttpClient

    Simply declarate the method StarDownLoad with async and the Task needs await. Here is a simple example, does no downloading. The form remains responsive.

    Two buttons, one ProgressBar.

    Code:
    Imports System.Threading
    ''' <summary>
    ''' Simple example for IProgress show progress with ProgressBar.
    ''' Note the method AsyncMethod should really be in a class that
    ''' has an event which the form subscribes too for updating the
    ''' ProgressBar.
    ''' </summary>
    Public Class ProgressForm
        Private _cts As New CancellationTokenSource()
        Private Sub ReportProgress(value As Integer)
    
            ProgressBar1.Value = value
    
        End Sub
        Private Async Function AsyncMethod(progress As IProgress(Of Integer), ct As CancellationToken) As Task
    
            For index As Integer = 0 To 100
    
                Await Task.Delay(1)
    
                If ct.IsCancellationRequested Then
                    ct.ThrowIfCancellationRequested()
                End If
    
                If progress IsNot Nothing Then
                    progress.Report(index)
                End If
    
            Next
    
        End Function
        Private Async Sub StartButton_Click(sender As Object, e As EventArgs) _
            Handles StartButton.Click
    
            ProgressBar1.Value = 0
            Await Task.Delay(1)
    
            Dim cancelled = False
    
            If _cts.IsCancellationRequested = True Then
                _cts.Dispose()
                _cts = New CancellationTokenSource()
            End If
    
            Dim progressIndicator = New Progress(Of Integer)(AddressOf ReportProgress)
    
            Try
    
                Await AsyncMethod(progressIndicator, _cts.Token)
    
            Catch ex As OperationCanceledException
                cancelled = True
            End Try
    
            If cancelled Then
                Await Task.Delay(1000)
            End If
        End Sub
    
        Private Sub CancelButton_Click(sender As Object, e As EventArgs) _
            Handles CancelButton.Click
    
            _cts.Cancel()
    
        End Sub
    End Class

  3. #3

    Thread Starter
    Member
    Join Date
    Jul 2013
    Posts
    49

    Re: [vb.net] How to use a progress bar while downloading through HttpClient

    Quote Originally Posted by kareninstructor View Post
    Simply declarate the method StarDownLoad with async and the Task needs await. Here is a simple example, does no downloading. The form remains responsive.

    Two buttons, one ProgressBar.

    Code:
    Imports System.Threading
    ''' <summary>
    ''' Simple example for IProgress show progress with ProgressBar.
    ''' Note the method AsyncMethod should really be in a class that
    ''' has an event which the form subscribes too for updating the
    ''' ProgressBar.
    ''' </summary>
    Public Class ProgressForm
        Private _cts As New CancellationTokenSource()
        Private Sub ReportProgress(value As Integer)
    
            ProgressBar1.Value = value
    
        End Sub
        Private Async Function AsyncMethod(progress As IProgress(Of Integer), ct As CancellationToken) As Task
    
            For index As Integer = 0 To 100
    
                Await Task.Delay(1)
    
                If ct.IsCancellationRequested Then
                    ct.ThrowIfCancellationRequested()
                End If
    
                If progress IsNot Nothing Then
                    progress.Report(index)
                End If
    
            Next
    
        End Function
        Private Async Sub StartButton_Click(sender As Object, e As EventArgs) _
            Handles StartButton.Click
    
            ProgressBar1.Value = 0
            Await Task.Delay(1)
    
            Dim cancelled = False
    
            If _cts.IsCancellationRequested = True Then
                _cts.Dispose()
                _cts = New CancellationTokenSource()
            End If
    
            Dim progressIndicator = New Progress(Of Integer)(AddressOf ReportProgress)
    
            Try
    
                Await AsyncMethod(progressIndicator, _cts.Token)
    
            Catch ex As OperationCanceledException
                cancelled = True
            End Try
    
            If cancelled Then
                Await Task.Delay(1000)
            End If
        End Sub
    
        Private Sub CancelButton_Click(sender As Object, e As EventArgs) _
            Handles CancelButton.Click
    
            _cts.Cancel()
    
        End Sub
    End Class

    Hi Karen thanks for your reply. I'd like to know where and how I should insert a Download in your code. My problem is that I know how to download, I just don't know how to make it work completely with your code/mine or viceversa.
    I assume It won't be enough just to create a webclient and make a download async, How can I "connect" the download with your async example code?
    Thanks

  4. #4
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    105,601

    Re: [vb.net] How to use a progress bar while downloading through HttpClient

    Look at the code. It contains this call:
    vb.net Code:
    1. Await AsyncMethod(progressIndicator, _cts.Token)
    to this method:
    vb.net Code:
    1. Private Async Function AsyncMethod(progress As IProgress(Of Integer), ct As CancellationToken) As Task
    So the example shows you how to make a call to an asynchronous method that takes IProgress(Of Integer) and CancellationToken objects as arguments and display progress from that method. Do you have any asynchronous methods in your code that take arguments of those types that you might want to call and display progress from?

  5. #5
    New Member
    Join Date
    Sep 2020
    Posts
    1

    Re: [vb.net] How to use a progress bar while downloading through HttpClient

    Quote Originally Posted by kareninstructor View Post
    Simply declarate the method StarDownLoad with async and the Task needs await. Here is a simple example, does no downloading. The form remains responsive.

    Two buttons, one ProgressBar.

    Code:
    Imports System.Threading
    ''' <summary>
    ''' Simple example for IProgress show progress with ProgressBar.
    ''' Note the method AsyncMethod should really be in a class that
    ''' has an event which the form subscribes too for updating the
    ''' ProgressBar.
    ''' </summary>
    Public Class ProgressForm
        Private _cts As New CancellationTokenSource()
        Private Sub ReportProgress(value As Integer)
    
            ProgressBar1.Value = value
    
        End Sub
        Private Async Function AsyncMethod(progress As IProgress(Of Integer), ct As CancellationToken) As Task
    
            For index As Integer = 0 To 100
    
                Await Task.Delay(1)
    
                If ct.IsCancellationRequested Then
                    ct.ThrowIfCancellationRequested()
                End If
    
                If progress IsNot Nothing Then
                    progress.Report(index)
                End If
    
            Next
    
        End Function
        Private Async Sub StartButton_Click(sender As Object, e As EventArgs) _
            Handles StartButton.Click
    
            ProgressBar1.Value = 0
            Await Task.Delay(1)
    
            Dim cancelled = False
    
            If _cts.IsCancellationRequested = True Then
                _cts.Dispose()
                _cts = New CancellationTokenSource()
            End If
    
            Dim progressIndicator = New Progress(Of Integer)(AddressOf ReportProgress)
    
            Try
    
                Await AsyncMethod(progressIndicator, _cts.Token)
    
            Catch ex As OperationCanceledException
                cancelled = True
            End Try
    
            If cancelled Then
                Await Task.Delay(1000)
            End If
        End Sub
    
        Private Sub CancelButton_Click(sender As Object, e As EventArgs) _
            Handles CancelButton.Click
    
            _cts.Cancel()
    
        End Sub
    End Class
    karen you look good,i like you

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width