2012-08-22 65 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