Wait Until UploadFileAsync is completed with progressbar

  • VB.NET

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von Michel21.

    Wait Until UploadFileAsync is completed with progressbar

    Hallo zusammen,

    nachdem ich mich jetzt mehrere Stunden durch Google und sämtliche MSDN, VB und sonstige Foren gekämpft habe, muß ich jetzt doch mal hier einen Thread eröffnen...

    Folgende Anforderung:

    - Ich möchte ein ZIP-File auf einen FTP-Server hochladen (funktioniert)

    - Während dem Upload soll eine Form mit einer ProgressBar eingeblendet werden (funktioniert teilweise)

    - Der Thread, der den Upload aufruft, darf erst mit der Abarbeitung fortfahren, wenn der Upload Completed ist (funktioniert nicht)



    Zum Thema ProgressBar:

    Meine Anwendung ist eine Windows Forms Anwendung, die beim Starten keine Form aufruft, sondern ein eine Prozedur in einem Modul.

    In dieser Prozedur wird an einer Stelle dir Funktion FTP-Upload gerufen. Hier wird ein Verzeichnis auf dem FTP-Server erstellt (funktioniert) und dann in das Verzeichnis ein ZIP-File hochgeladen (funktioniert auch).

    Vor dem Upload starte ich die Form frmUploadProgress.Show(), in der die ProgressBar pbUpload und ein Label lblUploadProgress enthalten ist.

    1. Problem: Die Form wird angezeigt, aktualisiert sich aber nicht.

    2. Problem: Um den Thread nicht zu blockieren bis der Upload completed ist, wird ja UploadFileAsync verwendet. Hat allerdings zur Folge, dass die Abarbeitung des Codes weiter läuft, auch wenn der Upload noch nicht beendet ist. Nach dem Upload wird jedoch eine Funktion gerufen, die das File löschen soll, welches hochgeladen wurde. Hier läuft die Application immer in einen Fehler, da der WebClient das File ja noch im Zugriff hat. Also muß ich sicherstellen, dass die Abarbeitung des Codes erst fortgeführt wird, wenn der Upload erfolgreich completed ist.





    PublicFunction FTPUpload(ByVal Foldername AsString, ByVal File AsString) AsBoolean



    Dim FTPCredentials AsNew Net.NetworkCredential("User", "Password")
    Dim WC AsNew Net.WebClient
    WC.Credentials = FTPCredentials
    AddHandler WC.UploadProgressChanged, AddressOf UploadProgressChanged
    AddHandler WC.UploadFileCompleted, AddressOf UploadFileCompleted



    Dim FTPrequest As Net.FtpWebRequest = CType(Net.FtpWebRequest.Create(Foldername), Net.FtpWebRequest)
    With FTPrequest
    .UseBinary = True

    .Credentials = FTPCredentials

    .Method = Net.WebRequestMethods.Ftp.MakeDirectory

    EndWith

    Try

    Using response As Net.FtpWebResponse = DirectCast(FTPrequest.GetResponse(), Net.FtpWebResponse)
    Try

    frmUploadProgress.Show()

    WC.UploadFileAsync(address:= New Uri(Foldername & File), fileName:="C:\Temp\Versand\" & File)
    FTPUpload = True

    Catch ex As Exception
    MsgBox( "#10013" & vbCrLf & "Der Versandordner konnte nicht hochgeladen werden!" & vbCrLf & vbCrLf & ex.Message, MsgBoxStyle.Critical, "Upload fehlgeschlagen")
    FTPUpload = False

    EndTry

    EndUsing

    Catch ex As Exception
    EndTry

    WC.Dispose()

    EndFunction



    PrivateSub UploadProgressChanged(ByVal sender AsObject, ByVal e As System.Net.UploadProgressChangedEventArgs)
    If frmUploadProgress.pbUpload.InvokeRequired Then

    frmUploadProgress.pbUpload.Invoke(
    New System.Net.UploadProgressChangedEventHandler(AddressOf UploadProgressChanged), sender, e)
    ExitSub

    EndIf

    frmUploadProgress.pbUpload.Value = e.ProgressPercentage

    frmUploadProgress.lblUploadProgress.Text = e.BytesSent.ToString( "0,0") & "Byte(s) von " & e.TotalBytesToSend.ToString("0,0") & " Byte(s) hochgeladen (" & (e.BytesSent / e.TotalBytesToSend).ToString("P") & ")"

    frmUploadProgress.Refresh()

    EndSub


    PrivateSub UploadFileCompleted(ByVal sender AsObject, ByVal e As System.ComponentModel.AsyncCompletedEventArgs)
    frmUploadProgress.Hide()

    EndSub


    Ich hoffe, mir kann hier jemand weiter helfen.

    Vielen Dank von meinem geschunden Hirn :)
    Hey,

    Kannst du den VB-Tag im Editor verwenden, damit wir deinen Code besser lesen können. Dann ist es für andere auch einfacher dir zu helfen ;)

    Gruß
    Youtube Info Library 2013 jetzt im Showroom.

    Jonas Jelonek schrieb:

    Eigentlich sollte es funktionieren, wenn du die Funktion, welche die Datei löscht, erst im UploadFileCompleted-Event ausführst, da dieses Event erst ausgelöst wird, wenn der Upload fertiggestellt wurde.





    Hi,

    danke für den Tipp, der bestimmt auch funktionieren würde, wenn die Funktion FilesLöschen die einzige Funktion nach dem Upload wäre. Ich muß allerdings nach dem ersten Upload einen weiteren Upload ausführen, noch eine eMail mit den Links versenden und noch ein paar andere Funktionen aufrufen.

    Das müsste ich dann alles in dem UploadFileEvent ausführen, was ich für unglücklich halte.



    Ich hatte auch schon die Idee, eine Variable done as boolean zu definieren und nachdem ich dem Upload gestartet hab, so lange in einer do while-Schleife zu bleiben, bis ich mit UploadFileEvent done auf true setze.

    Allerdings wird dann auch die frmUploadProgress nicht mehr aktualisiert, wahrscheinlich weil er das UploadProgressChanges-Event nicht mehr sauber händeln kann (nur so eine Theorie).

    Hält jemand die do while Schleife für eine gute Idee?

    Gruß
    Die while-Schleife ist m.M.n. eine nicht so gute Idee. Ich denke du könntest, wenn der erste Upload fertig ist, die Funktion zum Dateien löschen aufrufen und dann den zweiten Upload starten. Wenn der zweite Upload fertig ist, könntest du die anderen Funktionen aufrufen, wenn es nötig ist auch einen neuen Thread für diese initialisieren.

    Gruß Jonas Jelonek

    Jonas Jelonek schrieb:

    Die while-Schleife ist m.M.n. eine nicht so gute Idee. Ich denke du könntest, wenn der erste Upload fertig ist, die Funktion zum Dateien löschen aufrufen und dann den zweiten Upload starten. Wenn der zweite Upload fertig ist, könntest du die anderen Funktionen aufrufen, wenn es nötig ist auch einen neuen Thread für diese initialisieren.

    Gruß Jonas Jelonek



    Danke für die Idee mit den Threads. Werde mich nach meinem wohlverdienten Urlaub mal mit der Möglichkeit befassen, beide Uploads in einen Thread zu packen und den Main-Thread auf die anderen beiden warten lassen. Mal sehen, ob das funzt...



    Gruß + bis in 2 Wochen :)

    Michel21 schrieb:

    Danke für die Idee mit den Threads. Werde mich nach meinem wohlverdienten Urlaub mal mit der Möglichkeit befassen, beide Uploads in einen Thread zu packen und den Main-Thread auf die anderen beiden warten lassen. Mal sehen, ob das funzt...



    Threads sind immer eine gute Idee :)

    Für alle, die auch an diesem Problem hängen:


    Fügt in Eure Klasse

    VB.NET-Quellcode

    1. Private _WaitHandle_FTPUploadDone As New System.Threading.AutoResetEvent(False)


    ein und im Sub dann folgendes:

    VB.NET-Quellcode

    1. Dim FTPUpload As New Threading.Thread(AddressOf FTP.StartFTPUpload)
    2. FTPUpload.Start()
    3. _WaitHandle_FTPUploadDone.WaitOne()



    Der eigentliche Upload läuft dann in dem zweiten Sub (bei mir im Modul FTP im Sub StartFTPUpload)

    Im UploadFileCompleted-Handler des WebClients dann die Variable _WaitHandle_FTPUploadDone mit .Set() signalisieren.



    Beste Grüße

    Michael