Question

Thanks for reading - I am using the class below to calculate the CRC32 checksum of a specified file.

My question is how would I go about reporting the progress of file completion (in %) to a progressbar on a different form. I have tried (i / count) * 100 under the New() sub but I am not having any luck, or setting the progress bar with it for that matter. Can anyone help?

Thanks in advance

Steve

Public Class CRC32

Private crc32Table() As Integer
Private Const BUFFER_SIZE As Integer = 1024

Public Function GetCrc32(ByRef stream As System.IO.Stream) As Integer

    Dim crc32Result As Integer
    crc32Result = &HFFFFFFFF

    Dim buffer(BUFFER_SIZE) As Byte
    Dim readSize As Integer = BUFFER_SIZE

    Dim count As Integer = stream.Read(buffer, 0, readSize)
    Dim i As Integer
    Dim iLookup As Integer

    Do While (count > 0)
        For i = 0 To count - 1

            iLookup = (crc32Result And &HFF) Xor buffer(i)
            crc32Result = ((crc32Result And &HFFFFFF00) \ &H100) And &HFFFFFF
            crc32Result = crc32Result Xor crc32Table(iLookup)
        Next i


        count = stream.Read(buffer, 0, readSize)
    Loop

    GetCrc32 = Not (crc32Result)

End Function

Public Sub New()


    Dim dwPolynomial As Integer = &HEDB88320
    Dim i As Integer, j As Integer

    ReDim crc32Table(256)
    Dim dwCrc As Integer

    For i = 0 To 255
    Form1.CRCWorker.ReportProgress((i / 255) * 100)  'Report Progress
        dwCrc = i
        For j = 8 To 1 Step -1
            If (dwCrc And 1) Then
                dwCrc = ((dwCrc And &HFFFFFFFE) \ 2&) And &H7FFFFFFF
                dwCrc = dwCrc Xor dwPolynomial
            Else
                dwCrc = ((dwCrc And &HFFFFFFFE) \ 2&) And &H7FFFFFFF
            End If
        Next j

        crc32Table(i) = dwCrc
    Next i

    'file complete
End Sub

End Class
  '------------- END CRC32 CLASS--------------
   '-------------- START FORM1 --------------------------
Private Sub CRCWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles CRCWorker.DoWork

 For i = CurrentInt To dgv.Rows.Count - 1
              CRCWorker.ReportProgress(0, i & "/" & Total_Files)
              Current_File_Num = (i + 1)
              SetControlText(lblCurrentFile, Str(Current_File_Num) & "/" & Total_Files)
              result = CheckFile(SFV_Parent_Directory & "\" & dgv.Rows(i).Cells(0).Value, dgv.Rows(i).Cells(1).Value)
           Select Case result
               Case 0 ' missing file
                   UpdateRow(i, 2, "MISSING")
                   'dgv.Rows(i).Cells(2).Value = "MISSING"
                    Missing_Files = Missing_Files + 1
                    SetControlText(lblMissingFiles, Str(Missing_Files))
               Case 1 ' crc match
                    UpdateRow(i, 2, "OK")
                  ' dgv.Rows(i).Cells(2).Value = "OK"
                    Good_Files = Good_Files + 1
                    SetControlText(lblGoodFiles, Str(Good_Files))
              Case 2 'crc bad
                    UpdateRow(i, 2, "BAD")
                    ' dgv.Rows(i).Cells(2).Value = "BAD"
                    Bad_Files = Bad_Files + 1
                    SetControlText(lblBadFiles, Str(Bad_Files))
            End Select
            If CRCWorker.CancellationPending = True Then
                e.Cancel = True
                Exit Sub
            End If


      Next
       End Sub
    Private Sub CRCWorker_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles CRCWorker.ProgressChanged

    Dim val As Integer = e.ProgressPercentage
    ProgressBar2.Maximum = 100
    ProgressBar2.Value = e.ProgressPercentage
    Debug.Print(val)

    End Sub

     Function CheckFile(ByVal tocheck_filepath As String, ByVal expected_crc As String) As Integer 'returns result of a file check 0 = missing 1 = good 2 = bad

    If File.Exists(tocheck_filepath) = False Then
        Return 0 'return file missing
    End If
    Dim f As FileStream = New FileStream(tocheck_filepath, FileMode.Open, FileAccess.Read, FileShare.Read, 8192)
    Dim c As New CRC32()

    crc = c.GetCrc32(f)
    Dim crcResult As String = "00000000"
    crcResult = String.Format("{0:X8}", crc) 
    f.Close()

End Function
Was it helpful?

Solution

In Windows Forms BackgroundWorker Class is often used to run intensive tasks in another thread and update progress bar without blocking the interface. Example of using BackgroundWorker in VB.Net

The problem is when you use use the form in your code without instantiating it Form1.CRCWorker.ReportProgress((i / 255) * 100) there is a kind of hidden "auto-instantiation" happening and new instance of Form1 is created each time.

OTHER TIPS

It appears your .ReportProgress() call is in the New() subroutine, which is the part that makes the lookup table for the CRC calculation. The New() subroutine is called once, before the main CRC routine. The main CRC routine is the one that takes up all the time and needs the progress bar.

Shouldn't the progress bar updating be in the GetCrc32() function? Something like this:

    Public Function GetCrc32(ByRef stream As System.IO.Stream, _
                             Optional prbr As ProgressBar = Nothing) As UInteger
    Dim crc As UInteger = Not CUInt(0)
    Dim buffer(BUFFER_SIZE) As Byte
    Dim readSize As Integer = BUFFER_SIZE
    Dim left As Long = stream.Length
    If Not (prbr Is Nothing) Then ' ProgressBar setup for counting down amount left.
        prbr.Maximum = 100 
        prbr.Minimum = 0 
        prbr.Value = 100
    End If
    Dim count As Integer : Do
        count = stream.Read(buffer, 0, readSize)
        For i As Integer = 0 To count - 1
            crc = (crc >> 8) Xor tbl((crc And 255) Xor buffer(i))
        Next
        If Not (prbr Is Nothing) Then ' ProgressBar updated here
            left -= count 
            prbr.Value = CInt(left * 100 \ stream.Length)
            prbr.Refresh()
        End If
    Loop While count > 0
    Return Not crc
End Function
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top