2012-08-22 33 views
0

感谢您的阅读 - 我正在使用下面的类来计算指定文件的CRC32校验和。如何添加ProgressBar到计算CRC.NET中CRC32校验和的代码?

我的问题是我将如何去报告文件完成进度(%)到不同形式的进度条。我在New()子版下试过(i/count)* 100,但我没有任何运气,或者为它设置了进度条。谁能帮忙?提前

感谢

史蒂夫

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 
+1

你使用WinForms,WPF,WebForms? –

+0

嗨感谢您的回复,我使用WinForms – Nookster

回答

1

在Windows窗体BackgroundWorker Class经常被用来运行在另一个线程密集型任务,也不会妨碍界面更新进度条。 Example在VB.Net

使用BackgroundWorker的问题是,当你使用使用的形式在代码中没有实例它Form1.CRCWorker.ReportProgress((i/255) * 100)有一种隐藏的“auto-instantiation”发生和Form1新的实例每次被创建。

+0

当然,我使用的BackgroundWorker,但只是调用没有实际包含它的子。是否只有这样才能在自己的后台工作者中使用这段代码?谢谢。 – Nookster

+0

在DoWork事件处理程序中,我们执行我们的任务(调用New和GetCrc32方法)。在每次迭代中,我们都调用BackgroundWorker实例上的ReportProgress方法。 在ProgressChanged事件处理程序中,我们将ProgressBar的值设置为ProgressChangedEventArgs参数的ProgressPercentage属性。这将依次为1到100的值。 –

+0

是的,我目前正在这样做,我使用这种方法报告文件列表的进度,但是我希望也报告当前正在检查的文件的进度(而不是文件列表的进度),并最终报告速度当它正在读取3mb/s等时,就像它正在检查一个大文件时,它看起来好像什么也没有做。我将如何去做这件事?谢谢。 – Nookster

2

看起来您的.ReportProgress()调用位于New()子例程中,该子例程是为CRC计算生成查找表的部分。在主CRC例程之前,New()子例程被调用一次。主要的CRC例程是一直占用并需要进度条的例程。

不应该在GetCrc32()函数中更新进度栏吗?这样的事情:

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 
+0

刚刚注意到您的讨论室聊天内容,您发现progressBar更新需要在GetCrc32()例程中,但仍然卡住。它正在卡住,因为progressBar的分数计算是基于循环迭代器在缓冲区中的位置而不是缓冲区在流中的位置。 – eric