Sida 1 av 2

VB.net hur lägger jag till en progressbar till detta

Postat: 2 mars 2012, 02:04:51
av gOry
Ja som rubriken skriver så skulle jag villja ha en progressbar till denna kodsnutt.
Koden är en CRC32 Calculator

Kod: Markera allt

    Public Function GetCRC32(ByVal sFileName As String) As String
        Try
            Dim FS As FileStream = New FileStream(sFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 8192)
            Dim CRC32Result As Integer = &HFFFFFFFF
            Dim Buffer(4096) As Byte
            Dim ReadSize As Integer = 4096
            Dim Count As Integer = FS.Read(Buffer, 0, ReadSize)
            Dim CRC32Table(256) As Integer
            Dim DWPolynomial As Integer = &HEDB88320
            Dim DWCRC As Integer
            Dim i As Integer, j As Integer, n As Integer
            'Create CRC32 Table
            For i = 0 To 255
                ProgressBar1.Value = i
                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

            'Calcualting CRC32 Hash
            Do While (Count > 0)

                For i = 0 To Count - 1
                    n = (CRC32Result And &HFF) Xor Buffer(i)
                    CRC32Result = ((CRC32Result And &HFFFFFF00) \ &H100) And &HFFFFFF
                    CRC32Result = CRC32Result Xor CRC32Table(n)
                Next i
                Count = FS.Read(Buffer, 0, ReadSize)
            Loop
            Return Hex(Not (CRC32Result))

        Catch ex As Exception
            Return ""
        End Try
    End Function

Re: VB.net hur lägger jag till en progressbar till detta

Postat: 2 mars 2012, 05:00:10
av Horatius
Du måste nog tråda den på endera viset. Enklast torde vara att använda en backgroundworker och rapportera progress via ProgressChanged-metoden.

Re: VB.net hur lägger jag till en progressbar till detta

Postat: 2 mars 2012, 16:08:04
av gOry
Vad är de för skillnad mot att lägga koden direkt i loopen?
Problemet är att jag inte riktigt vet hur många gånger sista loopen går.

Re: VB.net hur lägger jag till en progressbar till detta

Postat: 2 mars 2012, 16:14:04
av Icecap
Om du inte vet hur långt snöret är kan du knappast ange hur långt på snöret du har kommit.

Re: VB.net hur lägger jag till en progressbar till detta

Postat: 2 mars 2012, 16:21:57
av gOry
Men de är det jag vill ha hjälp med :)

Kod: Markera allt

Do While (Count > 0)

                For i = 0 To Count - 1
                    n = (CRC32Result And &HFF) Xor Buffer(i)
                    CRC32Result = ((CRC32Result And &HFFFFFF00) \ &H100) And &HFFFFFF
                    CRC32Result = CRC32Result Xor CRC32Table(n)
                Next i
                Count = FS.Read(Buffer, 0, ReadSize)
            Loop
Return Hex(Not (CRC32Result))
Jag vet vad Count är innan loopen sätter igång.
men detta ställer till de Count = FS.Read(Buffer, 0, ReadSize)

Re: VB.net hur lägger jag till en progressbar till detta

Postat: 2 mars 2012, 16:29:34
av swesysmgr
gOry skrev:Vad är de för skillnad mot att lägga koden direkt i loopen?
Problemet är att jag inte riktigt vet hur många gånger sista loopen går.
Det gör GUI:t ryckigt med mycket räknande eller IO på samma tråd och du får lägga in DoEvents för att få UI tråden att processa knapptryckning för Avbryt eller liknande.

Vill du bara att progressbaren skall röra sig så länge något händer för att användraren inte skall tro att programmet hängt sig så kan du öka maxvärdet (progressbarens totallängd) till det dubbla mot tidigare varje gång den når 90% av max.

Är det en fil du gör checksumma på så kanske du kan läsa av filens storlek först (Length) och höfta fram ett maxvärde för progressbaren utifrån det?

Du uppdaterar din ProgressBar i for-loopen 0-255 vill du göra det på fler ställen?

Re: VB.net hur lägger jag till en progressbar till detta

Postat: 2 mars 2012, 16:54:58
av gOry
i For i = 0 To 255 loopen är de inga problem att lägga till en processbar men de är ungefär bara halva arbetet.
I nästa loop blir de knepigare :S

Re: VB.net hur lägger jag till en progressbar till detta

Postat: 2 mars 2012, 17:42:20
av mri
Notera kommentaren "Create CRC32 Table" ovanför den första loopen. Den loopen skapar bara en uppslagstabell för att få den andra loopen att gå snabbare. Den första loopen skall INTE ha nån progressbar, den kommer att bli klar på "nolltid".
I den andra loopen "Calcualting CRC32 Hash" tar du en ny räknare (t.ex. Pos) som börjar från 0 och ökas med byten som läses från filen. Totala filstorleken finns i FS.Length. Progress från 0...100 kan då räknas med: Pos * 100 / FS.Length

Re: VB.net hur lägger jag till en progressbar till detta

Postat: 2 mars 2012, 20:37:06
av gOry
äh, jag får inte till de.
Funkar bra på mindre filer, men om filen är 150 000 000 byte så blir de en låsning så fort jag lägger till

x = x + 1
My_BgWorker.ReportProgress(CInt((x * 100) / FS.Length))

Som ni ser så har jag även försökt mig på backgroundworker, men lyckas inte få ut resultat då istället.

Re: VB.net hur lägger jag till en progressbar till detta

Postat: 3 mars 2012, 00:49:50
av swesysmgr
ProgressBar klarar nog bara int som input, du får dela ner värdet om det blir för stort.

Re: VB.net hur lägger jag till en progressbar till detta

Postat: 3 mars 2012, 08:27:41
av mri
Förstår du exakt vad den där koden gör, innan du försökte sätta in en progress bar? Om inte kan det nog vara knepigt...

Notera att andra loopen läser från filen i 4096 bytes block (ReadSize), och det lönar sig att endast göra den där progress beräkningen och updateringen en gång per block. Samt endast anropa My_BgWorker.ReportProgress() om progress värdet faktiskt ändrat.

Du behöver antagligen använda Invoke när du updaterar själva progress Form'en, eftersom anropet sannolikt kommer från en annan tråd (My_BgWorker). Gör du det?

Har du konfigurerat progress Form'en så att det visar progress mellan 0 ... 100 ?

Annat kan jag inte komma på utan att du visar mera av din kod.

Re: VB.net hur lägger jag till en progressbar till detta

Postat: 3 mars 2012, 09:37:45
av Micke_s
eftersom det är en fil så vet du hur långt snöret är.
kolla upp FileInfo...
Jag hade kört det i while loopen, då blir varje del av progressbar 4096byte stor.

sätt progressbar.maxvalue = cint(filesize/4096)+1;
och progressbar.value = 0

och i loopen progressbar.value = progressbar.value + 1.

Detta funkar så länge inte filen ändras under körning. kanske ska jämföra value och maxvalue för inte få en exception.

Kod: Markera allt

Private Function GetFileSize(ByVal MyFilePath As String) As Long
Dim MyFile As New FileInfo(MyFilePath)
Dim FileSize As Long = MyFile.Length
Return FileSize
End Function

Re: VB.net hur lägger jag till en progressbar till detta

Postat: 3 mars 2012, 11:38:01
av Horatius
VB verkar mycket snällare än C# vad det gäller uppdatering av formsen. skulle dock rekommendera en backgroundworker ändå.


Vad det gäller värdet så sätt progressreporterns max till 100, min till 0 och steps till1.

Lägg till en ny long före looparna.

Exempelvis: Dim pos As Long
pos = 0

Den första loopen är ointressant eftersom den går så fort.

Sedan :

Kod: Markera allt


     Do While (Count > 0)

                For i = 0 To Count - 1
                    n = (CRC32Result And &HFF) Xor Buffer(i)
                    CRC32Result = ((CRC32Result And &HFFFFFF00) \ &H100) And &HFFFFFF
                    CRC32Result = CRC32Result Xor CRC32Table(n)
                    pos = pos + 1 'nytt

                Next i

                Count = FS.Read(Buffer, 0, ReadSize)
                ProgressBar1.Value = (pos / FS.Length) * 100 ' nytt
            Loop


Om FS.Length är noll så kastar den ett präktigt fel men det kanske inte är ett issue.

Re: VB.net hur lägger jag till en progressbar till detta

Postat: 3 mars 2012, 12:55:54
av mri
OK, med reservation för att jag egentligen inte kan BASIC, men det här blir antagligen inte rätt:

Kod: Markera allt

ProgressBar1.Value = (pos / FS.Length) * 100
Eftersom pos och FS.Length är heltal skall uttrycket skrivas:

Kod: Markera allt

ProgressBar1.Value = (pos * 100) / FS.Length

Re: VB.net hur lägger jag till en progressbar till detta

Postat: 3 mars 2012, 14:56:32
av gOry
tack, så nu har de börjat funka. Måste vart att jag inte satte min pos As long... :doh:
Även min backgroundworker funkar fint nu.

Några tips på hur man kan göra räknaren snabbare?