Download blob from mysql database with progressbar

I’m working on a Winform program where a user can download a large blob file. To visualize the progress I have added a progressbar on the form. Downloading the blob works fine, but I can’t figure out how to update the progress bar during download.

This is what I have so far…

        Private Sub frmMeldingNieuweVersie_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        
        ProgressBar1.Minimum=0
        ProgressBar1.Maximum=100
        ProgressBar1.Value=10
        BackgroundWorker1.RunWorkerAsync()
    
        
    End Sub
    
    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
            Dim objReader As MySqlDataReader
            Dim connectionString As String = ConfigurationManager.ConnectionStrings("MySqlConnectionString").ToString()
            dim filename As String = "setup.exe"
            dim setupFile As String
            Dim strLatestVersion As String
            Dim bytesLoad As Byte()
    
            Try
                myCmd.Connection = myConnection.Open
                myCmd.CommandText = "SELECT setupFile, OCTET_LENGTH(SetupFile) AS FileSize FROM Versiebeheer ORDER BY Versienummer DESC LIMIT 1"
                objReader = myCmd.ExecuteReader
    
                While objReader.Read
                    'BackgroundWorker1.ReportProgress(e.percentProgress)
                    If objReader.HasRows Then
    
                        strLatestVersion = Replace(objReader("Versienummer"),".","")
    
                            If Not IsDBNull(objreader("setupFile")) then
                                bytesLoad = DirectCast(objReader("setupFile"), Byte())
                                setupFile = "C:Temp" & filename
                            End If
                        objReader.Close()
                        objReader = Nothing
                    End If
    
                End While
                
                myConnection.Close()
            Catch ex As Exception
                MessageBox.Show(ex.Message)
                myConnection.Close()
            End Try
        End Sub

Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
        Invoke(Sub()
            Me.ProgressBar1.Value = 50'e.ProgressPercentage
        End Sub)
    End Sub

    Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        'Close()
    End Sub

Is it possible to make a progress bar for this problem or am I doing something wrong?

Answer

I’ve found the solution for my problem. Here is the working code for the progress bar. The reason why the backgroundworker didn’t worked was because the WorkerReportsProgress was set to False.

    Private Sub frmMeldingNieuweVersie_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    ProgressBar1.Minimum = 0
    ProgressBar1.Maximum = 100

    BackgroundWorker1.RunWorkerAsync()

End Sub
Private Sub backgroundWorker1_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    ' Get the BackgroundWorker object that raised this event.
    Dim worker As BackgroundWorker =
            CType(sender, BackgroundWorker)
    e.Result = RetrieveFile(worker, e)
End Sub
Private Function RetrieveFile(ByVal worker As BackgroundWorker, ByVal e As DoWorkEventArgs) As Byte()
    Dim objReader As MySqlDataReader
    Dim connectionString As String = ConfigurationManager.ConnectionStrings("MySqlConnectionString").ToString()

    Try
        myCmd.Connection = myConnection.Open
        myCmd.CommandText = "SELECT OCTET_LENGTH(SetupFile) AS fileSize, setupFile FROM Versiebeheer ORDER BY Versienummer DESC LIMIT 1"
        objReader = myCmd.ExecuteReader(CommandBehavior.SequentialAccess)

        While objReader.Read

            If objReader.HasRows Then

                Dim memory As New MemoryStream
                Dim startIndex As Long = 0
                Const ChunkSize As Integer = 256
                Dim totalSize As Long = objReader("fileSize")
                Dim progressPercentage As Integer

                Do
                    Dim buffer(ChunkSize - 1) As Byte

                    Dim retrievedBytes As Long = objReader.GetBytes(1, startIndex, buffer, 0, ChunkSize)

                    memory.Write(buffer, 0, CInt(retrievedBytes))

                    startIndex += retrievedBytes

                    progressPercentage = (startIndex / totalSize) * 100
                    worker.ReportProgress(progressPercentage)
                    lblPercentage.Invoke(New SetValueDelegate(AddressOf SetValue), New Object() {progressPercentage})

                    If retrievedBytes <> ChunkSize Then

                        Exit Do
                    End If
                Loop

                myCmd.Connection.Close()

                Dim data() As Byte = memory.ToArray()

                memory.Dispose()
                Return data

            End If

        End While


        myConnection.Close()
    Catch ex As Exception
        MessageBox.Show(ex.Message)
        myConnection.Close()
    End Try
End Function

Private Sub backgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged

    Me.ProgressBar1.Value = e.ProgressPercentage

End Sub

Public Delegate Sub SetValueDelegate(ByVal value As Integer)

Public Sub SetValue(ByVal value As Integer)
    lblPercentage.Text = value.ToString() & "%"
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    Dim bytesLoad As Byte()
    Dim worker As BackgroundWorker =
            CType(sender, BackgroundWorker)
    ProgressBar1.Minimum = 0
    ProgressBar1.Maximum = 100

    Dim filename As String = "C:tmpsetup.exe"
    bytesLoad = e.Result
    Using fs As New FileStream(filename, FileMode.OpenOrCreate, FileAccess.Write)
        fs.Write(bytesLoad, 0, bytesLoad.Length)
        'Set image variable value using memory stream. 
        fs.Flush()
        fs.Close()
        btnInstalleerUpdate.Enabled = True
    End Using
End Sub

Leave a Reply

Your email address will not be published. Required fields are marked *