Entwickler-Ecke

WinForms - Erledigt: Progressbar will leider nicht


Findus - Fr 26.12.08 05:04
Titel: Erledigt: Progressbar will leider nicht
Hallo zusammen ..

Kaum ein Problem vom Hals, schon ist das nächste da. Ich hab meine Methoden nochmal etwas umgebaut. Als Doku diente mir das Galileo Computing Openbook (2005). Der Download scheint nun nur noch einmal durchzulaufen, aber dafür will die progressbar keinen Dienst mehr tun :(

Hier mal ein Codeauszug:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            // Der Worker wird später benötigt    
            // BackgroundWorker worker = sender as BackgroundWorker;

            //  Den Dateiabruf vorbereiten. 
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(remotefile);
            request.Method = "GET";
            HttpWebResponse hwrs = (HttpWebResponse)request.GetResponse();
            FileStream fs = new FileStream(localfile, FileMode.Append, FileAccess.Write);
            Stream input = hwrs.GetResponseStream();

            //  Berechne die Dateigrößen und den Abschnitt 
            int counter = 0;
            int buffer;
            int fileLength = (int)hwrs.ContentLength;
            
            while (true)
            {
                    // Hier download starten
                    buffer = input.ReadByte();
                    fs.WriteByte((byte)buffer);

                    // wenn Datei eingelesen, Schleife beenden
                    if (buffer == -1)
                    break;

                    //  Das Ereignis 'ProgressChanged' auslösen -> Bytes zählen
                    counter++;
                    this.backgroundWorker1.ReportProgress(counter * 100 / fileLength);
                }
            fs.Close();
            hwrs.Close();
         }
        
        // Dieser event handler updatet die progressbar
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (progressBar1.Value == 0)
            {
                Text = String.Format("Download {0} bytes", (int)e.UserState);
            }  
            progressBar1.Value = e.ProgressPercentage;
        }


Vielleicht hat mir ja wieder jemand nen Tip. Vielleicht ist es aber auch nur zu spät :) Aber dieses Zeugs ist ja wie eine Droge ... Achja WorkerReportsProgress und WorkerSupportsCancellation stehen auf true.

Gruß Findus


jaenicke - Fr 26.12.08 09:37

Das Event hast du ja zugewiesen hoffe ich. ;-)

Hast du mal einen Haltepunkt in das Event gesetzt und geschaut ob das Programm dort ankommt? Wenn es dort nicht ankommt, setze mal einen Haltepunkt auf den Aufruf von ReportProgress und schau ob das ausgeführt wird. (Aber das müsste es ja eigentlich werden.)


JüTho - Fr 26.12.08 12:00

Hallo,

zunächst einmal solltest Du die (neue) if-Abfrage vor das WriteByte setzen (Begründung sollte klar sein, oder?). Außerdem ist es eher Quatsch, ReportProgress bei jedem Byte aufzurufen; das war einer der Gründe für meinen früheren Vorschlag mit section.

Das Hauptproblem dürfte darin liegen, dass Du bei ReportProgress auf UserState verzichtest. Damit steht dort vermutlich null; ich habe keine Ahnung, was (int)e.UserState daraus macht und wie ProgressChanged darauf reagiert. Vielleicht bleibt aus diesem Grund die ProgressBar immer und ewig auf dem Wert 0 stehen.

Aber jaenicke hat recht: Du solltest Dir angewöhnen, selbst mit dem Debugger an kritische Stellen zu gehen (dafür gibt es ihn schließlich). Setze einen Haltepunkt auf Zeile 39, also den Anfang von ProgressChanged, vergleiche die Werte der EventArgs und prüfe, wie er im Einzelschritt-Modus weitergeht.

Gruß und nochmals Frohe (Rest-) Weihnachten! Jürgen


Findus - Fr 26.12.08 12:33

Hallo jaenicke und JüTho ..


Quelltext
1:
Das Event hast du ja zugewiesen hoffe ich. ;-)                    

:oops: :oops: :oops: - Ich gestehe alles ! :)

Hat aber auch was gutes das ich das vergessen habe, denn seit dem läuft der Download wieder 2 mal durch. Nehme ich aber den DoWork Event aus dem Initialize raus dann geht er einmal durch und aus ist.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
        private void InitializeBackgoundWorker()
        {
      /*      backgroundWorker1.DoWork += 
                new DoWorkEventHandler(backgroundWorker1_DoWork); */

            backgroundWorker1.RunWorkerCompleted += 
                new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
            backgroundWorker1.ProgressChanged += 
                new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
        }

Warum macht er das denn wohl ?

Gruß Findus


JüTho - Fr 26.12.08 12:50

user profile iconFindus hat folgendes geschrieben Zum zitierten Posting springen:
Hat aber auch was gutes das ich das vergessen habe, denn seit dem läuft der Download wieder 2 mal durch. Nehme ich aber den DoWork Event aus dem Initialize raus dann geht er einmal durch und aus ist.

Das deutet aber sehr darauf hin, dass "DoWork += " zweimal in Deinem Code enthalten ist - vielleicht einmal in der Designer.cs und einmal in Deiner InitializeBackgroundWorker-Methode.
Vielleicht hast Du (aus Test- und Vergleichszwecken) noch verschiedene DoWork-Methoden, einmal mit und einmal ohne ReportProgress.

Vielleicht solltest Du einmal "aufräumen" und alles auskommentieren, was aus früheren Versuchen noch übrig geblieben ist.

Gruß Jürgen


Findus - Fr 26.12.08 13:46

Hallo Jürgen,

so wie es aussieht habe ich den Übeltäter gefunden der für die doppelten Aufrufe verantworlich war. Stand tatsächlich nochmal ein Aufruf im Designer.

Gruß Findus