Fortschritt bei Upload anzeigen

Katzenbauer

Erfahrenes Mitglied
Hallo,

ich habe mir ein Programm geschrieben, dass eine Datei per http hochlädt (als Bestandtteil eines Formulars). Das klappt soweit ganz gut nur soll das Programm auch den Fortschritt des Uploads anzeigen.

Ich mache das folgendermaßen:

Ich baue ein http Packet per HttpWebRequest und schicke das dann an den Server. Bisher passiert das ganze synchron also im Gui Thread, was natürlich suboptimal ist, da bei einer größeren Datei das Programm ziemlich lange blockiert werden würde.
Also habe ich vor die ganze Uploadfunktion() in einen eigenen Thread auslagern. Soweit so gut. Nur wie kann ich jetzt den Status des Uploads abfragen?

In der Uploadfunktion befindet sich eine Schleife, die zu sendende Datei in 8 KB happen ließt und über den Stream schickt:

Code:
//  file is a filestream and httpStream the networkstream ;)
byte[] buffer = new byte[bufferSize];
int bytesToRead = bufferSize;
int bytesRead;
do
{
    // not enough bytes here to fill the whole buffer
    if ((file.Length - file.Position) < bufferSize)
    {
        bytesToRead = (int)(file.Length - file.Position);
    }
    bytesRead = file.Read(buffer, 0, bytesToRead);
    httpStream.Write(buffer, 0, bytesRead);
} while (bytesRead == bufferSize);
Also habe ich mir gedacht: Prima das kann man locker in der Schleife erledigen. Nur leider läuft die sofort durch, woran auch ein Flush() nichts ändert.

Da muss es doch was geben. Gibt ja genug Progamme die etwas ähnliches machen.
 
Hi,

Kann dir jetzt nur sagen, wie ich das bei einer GUI-Anwendung machen würde:
Da kannst du entweder per Invoke und Delegate auf GUI-Element zugreifen.
Alternative wäre die Nutzung eines BackgroundWorker (.NET 2.0). Diese Klasse ist speziell dafür gedacht. Altenativ kannst du dir ja das Beispiel in der MSDN anschauen, um zu sehen, wie der BackgroundWorker vom Prinzip her arbeitet
 
Ich weiß, dass ich per Invoke aus dem Thread auf GUI elemente zugreifen kann. Das ist auch kein Problem. Ich weiß nur nichtmal wie ich in dem Thread selbst den Fortschritt festellen kann.

Ich schicke das über den Stream und fertig. Ich habe also keine Kontrolle mehr über den Upload.
 
Hi,

Du weißt aber wie groß die Datei ist und kannst somit auch feststellen (da du weißt, wieviele Bytes du auf einmal überträgst) wieviel du schon übertragen hast.

Pseudocode:
percentage = uploaded / maxSize * 100
 
Das weiß ich doch selbst.

Die Frage ist. Wo bringe ich das nun unter? Wie gesagt die Schleife läuft sofort durch und die Übertragung findet erst bei stream.Close() statt. Ich habe also mit meinem Code keinen Einfluss mehr.
 
Doch hast Du. Definiere ein Event, löse innerhalb der Schleife aus und invoke es auf dem Thread des Forms. ;)
Das hier ist ein rudimentäres Beispielprogramm: [post=1337449]AW: Probleme beim neuzeichnen von pictureBox - Post[/post]
Hier findest unter anderem Techniken die Ereignisdaten über einen synchronisierten Queue zum mehreren Forms zu senden: [thread=199136]Threading hilfe - Thread[/thread]

[thread=260455]Multi-Threading - Teil1: Einführung - Tutorial[/thread]
 
Leute lest ihr überheupt was ich schreibe? ;)

Das Problem ist nicht der Thread sondern der FileUpload. Die Schleife ist total unbrauchbar um den Fortschritt festzustellen, weil sie sofort durchläuft und nicht wie zu erwarten nach und nach hochlädt.
 
Wozu eine Schleife, wenn Du die Datei in einem Zug uploadest. :suspekt: Was auch eigentlich gar nicht möglich ist. Müsstest ja dafür eine Paketgröße so groß wie die Datei verwenden. Dann würde die Schleife auch nur einmal durchlaufen. ;) :D

Na klar lädt deine Schleife Stück für Stück hoch. Nach httpStream.Write(buffer, 0, bytesRead); löst dein Ereignis aus. Verwende bitte eine Puffergröße zwischen 1024 - 4096.
 
Zuletzt bearbeitet:
Na klar lädt deine Schleife Stück für Stück hoch. Nach httpStream.Write(buffer, 0, bytesRead); löst dein Ereignis aus. Verwende bitte eine Puffergröße zwischen 1024 - 4096.

Also ich hatte das ganze mal in einem Konsolenprogramm getestet. Dann hab ich das Programm gestartet um eine 10MB Datei hochzuladen und es war sofort zuende. Der Upload lief jedoch die ganze Zeit weiter und wurde auch abgeschlossen.

Was meinst du das löst mein Ereignis aus? Das Ereignis muss ich doch dann selbst auslösen in der Schleife, oder?
 
Wenn Du dir mal die Links angeschaut hättest, die ich dir gepostet habe, wüsstest Du eigentlich was Du machen musst.
Wie man ein Event definiert siehst sehr genau in diesem Thread: [thread=219377]Eigene Eventhandler .... - Thread[/thread]
Jetzt schaust Dir noch die anderen Links an, ganz besonders den PictureBox-Post und Du solltest keine Probleme mehr haben. :)
 
Zurück