Entwickler-Ecke

Netzwerk - Position eines "WebResponse" ermitteln


Mindforce - Mi 04.04.12 17:43
Titel: Position eines "WebResponse" ermitteln
Moin moin,

ich möchte gerne erreichen, dass ich sehen kann, wieviel von X Bytes bereits heruntergeladen worden.
Mein Problem ist, dass ich durch Response.ContentLenght zwar die Länge der Datei ansehen kann (4000 bytes),
jedoch kann ich nicht die aktuelle Position des Downloads abrufen, um zu sehen, wie weit der Download bereits ist.

In einem gesonderten Thread rufe ich folgende Methode auf, um eine Datei durch WebResponse & einem Stream herunterzuladen:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
                HttpWebRequest WebRequestObject = (HttpWebRequest)HttpWebRequest.Create(packIdent[i]);

                WebRequestObject.UserAgent = "Mozilla 4.0/XXXXX";
                WebRequestObject.Referer = "http://google.com";
                WebRequestObject.AllowAutoRedirect = false;

                Response = WebRequestObject.GetResponse();

                Stream WebStream = Response.GetResponseStream();

                FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write);
                ReadWriteStream(WebStream, fs);

                WebStream.Close();
                Response.Close();


Jedoch wenn ich (aus einem anderen Thread) versuche, die aktuelle Position abzufragen mit Response.GetResponseStream().Position
schmeißt er mir eine Exception, in dem er sagt, dass keine Suchläufe erlaubt sein.
> Beim MSDN las ich, dass es evtl. daran liegt, dass die Klasse abgeleitet worden ist und die .Position nicht mitgenommen wurde.

Gibt es eine Lösung bzw. einen anderen Weg einen Datei herunterzuladen und den aktuellen Status anzusehen?

Hoffe ihr könnt helfen.


Mit freundlichen Grüßen,


Kha - Mi 04.04.12 18:26

Deine Methode ReadWriteStream wird wohl aus dem Response Stream lesen, also kannst du dort doch die Anzahl der bisher gelesenen Bytes mitzählen.

PS: Lokale Variablen werden normalerweise klein geschrieben.


Mindforce - Mi 04.04.12 18:51

user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
Deine Methode ReadWriteStream wird wohl aus dem Response Stream lesen, also kannst du dort doch die Anzahl der bisher gelesenen Bytes mitzählen.


ReadWriteStream wird natürlich nur dann ausgeführt, wenn der Stream bereits voll beschrieben ist (also nach dem Download). ReadWriteStream ist also unfähig mir den aktuellen Downloadstatus anzuzeigen.

MFG


Th69 - Mi 04.04.12 19:09

Hallo Mindforce,

das Stichwort lautet: asynchrone Datenübertragung.
Schau dir mal den folgenden Artikel dazu an: http://tomasp.net/blog/csharp-async.aspx (insbesondere die Methode ReadToEndAsync).


Mindforce - Mi 04.04.12 21:27

Okay, vielen Dank, asynchron war hier das richtige Stichwort.
Ich muss aber ehrlich gestehen mich jetzt schmutzig aus der Affaire gezogen zu haben.
Ich habe die Finger von Sockets & Streams etc. gelassen und mich auf einfache .NET Methoden zurückgezogen.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
        void T_DL() 
        {
            for (int i = 0; i < packIdent.Length; i++)
            {
                WebClient webClient = new WebClient();
                webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
                webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
                webClient.DownloadFileAsync(new Uri(packIdent[i]), path + @"\s."+i.ToString("00"));
            }
        }

        private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            Progress = (int)e.BytesReceived;
        }

        private void Completed(object sender, AsyncCompletedEventArgs e)
        {
            Progressed += Progress;
        }


Mit Threads arbeiten ist im Grunde hierbei garnichtmehr nötig und so ziemlich die einfachste Methode um Dateien herunterzuladen.
Und der Vorteil gegenüber meiner vorherigen Download-Prozedur: Ich kann mehrere Dateien aufeinmal herunterladen und kann somit die volle Bandbreite nutzen (wenn möglich).
Und vor allem wird mein int Progress (global) erhöht, kann ich dann ganz easy auslesen :D

"Gute" Lösung?

MFG


Kha - Do 05.04.12 00:50

user profile iconMindforce hat folgendes geschrieben Zum zitierten Posting springen:
ReadWriteStream wird natürlich nur dann ausgeführt, wenn der Stream bereits voll beschrieben ist (also nach dem Download).
Äh, nein. Das ist schließlich der ganze Sinn von Streams.

user profile iconMindforce hat folgendes geschrieben Zum zitierten Posting springen:
"Gute" Lösung?
Wenn dir die Fähigkeiten von WebClient ausreichen, spricht nichts dagegen :) . Aber deine Eventhandler sehen nicht so aus, als ob sie mit parallelen Downloads zurecht kämen?