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

Elektronik- och mekanikrelaterad mjukvara/litteratur. (T.ex schema-CAD, simulering, böcker, manualer mm. OS-problem hör inte hit!)
Användarvisningsbild
gOry
Inlägg: 5071
Blev medlem: 6 juni 2003, 22:41:25
Ort: Stockholm
Kontakt:

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

Inlägg 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
Horatius
Inlägg: 216
Blev medlem: 5 augusti 2008, 01:00:01
Ort: Kisa

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

Inlägg 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.
Användarvisningsbild
gOry
Inlägg: 5071
Blev medlem: 6 juni 2003, 22:41:25
Ort: Stockholm
Kontakt:

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

Inlägg 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.
Användarvisningsbild
Icecap
Inlägg: 26635
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

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

Inlägg 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.
Användarvisningsbild
gOry
Inlägg: 5071
Blev medlem: 6 juni 2003, 22:41:25
Ort: Stockholm
Kontakt:

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

Inlägg 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)
Användarvisningsbild
swesysmgr
Inlägg: 14924
Blev medlem: 28 mars 2009, 06:56:43
Ort: Göteborg

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

Inlägg 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?
Användarvisningsbild
gOry
Inlägg: 5071
Blev medlem: 6 juni 2003, 22:41:25
Ort: Stockholm
Kontakt:

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

Inlägg 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
Användarvisningsbild
mri
Inlägg: 1165
Blev medlem: 15 mars 2007, 13:20:50
Ort: Jakobstad, Finland
Kontakt:

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

Inlägg 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
Användarvisningsbild
gOry
Inlägg: 5071
Blev medlem: 6 juni 2003, 22:41:25
Ort: Stockholm
Kontakt:

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

Inlägg 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.
Användarvisningsbild
swesysmgr
Inlägg: 14924
Blev medlem: 28 mars 2009, 06:56:43
Ort: Göteborg

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

Inlägg av swesysmgr »

ProgressBar klarar nog bara int som input, du får dela ner värdet om det blir för stort.
Användarvisningsbild
mri
Inlägg: 1165
Blev medlem: 15 mars 2007, 13:20:50
Ort: Jakobstad, Finland
Kontakt:

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

Inlägg 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.
Användarvisningsbild
Micke_s
EF Sponsor
Inlägg: 6741
Blev medlem: 15 december 2005, 21:31:34
Ort: Malmö

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

Inlägg 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
Horatius
Inlägg: 216
Blev medlem: 5 augusti 2008, 01:00:01
Ort: Kisa

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

Inlägg 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.
Användarvisningsbild
mri
Inlägg: 1165
Blev medlem: 15 mars 2007, 13:20:50
Ort: Jakobstad, Finland
Kontakt:

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

Inlägg 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
Användarvisningsbild
gOry
Inlägg: 5071
Blev medlem: 6 juni 2003, 22:41:25
Ort: Stockholm
Kontakt:

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

Inlägg 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?
Skriv svar