Autor Beitrag
Sharpener
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 24

Win 95, Win 98, Win 2000, Win XP, Win Vista, Win 7, Win 8, Mac OS X 10.4, Mac OS X 10.7, Mac OS X 10.8
C# (VS 2012), SQL, PHP, HTML&CSS,Java
BeitragVerfasst: So 25.08.13 14:59 
Hallo,
ich will einen HTML Parser programmieren. Dazu soll zuerst eine HTML Seite aus dem Netz geladen werden. Eigentlich eine simple Aufgabe aber das System soll warten bis die Seite wirklich ganz geladen ist, um Fehler zu vermeiden.
So sieht die vorläufige Methode aus:
ausblenden 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:
class Downloader
    {
        Boolean fertig = false;
        public void downloadFile(String address)
        {
            string pfad = @"c:\Greyhound";
            if(!Directory.Exists(pfad))
            {
                Directory.CreateDirectory(pfad);
            }
            WebClient down = new WebClient();
            down.DownloadFileCompleted += (sender, e) =>
                {
                    if (e.Error == null)
                    {
                        doSomeThing();
                    }
                };
            down.DownloadFileAsync(new Uri(address), @"c:\Greyhound\page.html");
        }
        public void doSomeThing()
        {
            MessageBox.Show("FERTIG");
        }

Und Aufgerufen wird die Methode von hier:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
public partial class MainWindow : Form
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void GoButton_Click(object sender, EventArgs e)
        {
            Downloader down = new Downloader();
            down.downloadFile(Convert.ToString(AddressBox.Text));
        }

    }

Ich bin schon im Debugger das Programm durchgegangen finde meinen Fehler aber nicht. Das Programm läuft durch... es downloaded die Seite komplett. Aber die (vorläufige) Messagebox wird nicht angezeigt.
Wo liegt der Fehler? Ich habe jetzt gefühlte Tage darüber geguckt und den Fehler nicht gefunden.
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Chefentwickler
Beiträge: 20413
Erhaltene Danke: 2231

Win 10
C# (VS 2017)
BeitragVerfasst: So 25.08.13 15:48 
Ich bin gerade nicht sicher, ob die Instanz down nach dem Ende der Methode noch lange genug lebt, um das Event aufzurufen. Aber benutz' doch die neuen Async-Features von C# :-)

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
        private async void button1_Click(object sender, EventArgs e)
        {
            var wc = new WebClient();
            string data = await wc.DownloadStringTaskAsync("http://www.entwickler-ecke.de");
            textBox1.Text = data;
        }

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Sharpener Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 24

Win 95, Win 98, Win 2000, Win XP, Win Vista, Win 7, Win 8, Mac OS X 10.4, Mac OS X 10.7, Mac OS X 10.8
C# (VS 2012), SQL, PHP, HTML&CSS,Java
BeitragVerfasst: So 25.08.13 17:21 
Stellt also...
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
public async void downloadFile(String address)
        {
            string pfad = @"c:\Greyhound";
            if(!Directory.Exists(pfad))
            {
                Directory.CreateDirectory(pfad);
            }
            WebClient down = new WebClient();
            await down.DownloadFileTaskAsync(new Uri(address), @"c:\Greyhound\page.html");
        }

...sicher, dass die Methode erst dann abschließt wenn der Download fertig ist? Hatte noch nicht viel mit async zu tun.
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Chefentwickler
Beiträge: 20413
Erhaltene Danke: 2231

Win 10
C# (VS 2017)
BeitragVerfasst: So 25.08.13 20:51 
Ja, wenn Du die Methode mit await aufrufst.

Was bei Verwendung von await passiert: Die Methode, die mit await aufgerufen wird, wird in einem separaten Thread (als Task) aufgerufen. Damit bleibt zum Beispiel die GUI reaktionsfähig, weil der Hauptthread nicht blockiert ist. Wenn also bei Deinem Quelltext Zeile 9 erreicht ist, wird das Herunterladen gestartet und die Methode erst einmal verlassen. Sobald dies fertig ist, wird wieder in die Methode gesprungen und der Rest (bei Dir: nichts) abgearbeitet.

Wenn Du Deine Methode mit await aufrufst, wird ebenso verfahren. Deine Methode wird in einem separeten Thread abgearbeitet und alles, was danach kommt, wartet ohne zu blockieren.

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".