BakgroundWorker und DownloadFileAsync

  • VB.NET

Es gibt 36 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    BakgroundWorker und DownloadFileAsync

    EDIT: Hier ist die Lösung in dem Spoiler


    Hallo Community,

    Ich wahr gerade mal das neue Foren System am durchstöbern als ich über ein Tutorial gestolpert bin von dem Backgroundworker.

    Nun habe ich dies mal nach geschrieben wie es ungefähr im Tutorial der Fall wahr.
    Dies hat auch wunderschön funktioniert.

    Da hatte ich die Idee das ich es ja nochmals mit einem DownloadFileAsync versuchen könnte.

    Doch hier happert es gerade einwenig.

    VB.NET-Quellcode

    1. Public Class Form1
    2. Dim WithEvents BGW As New System.ComponentModel.BackgroundWorker With {.WorkerReportsProgress = True, .WorkerSupportsCancellation = True}
    3. Dim WithEvents wc As New System.Net.WebClient
    4. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    5. Dim Zeilen() As String
    6. Zeilen = Split(tb_files.Text, vbCrLf)
    7. Dim lin As Integer = CInt(UBound(Zeilen))
    8. MsgBox(lin)
    9. If Not BGW.IsBusy Then
    10. Label1.Text = "Download wird gestartet"
    11. Button1.Enabled = False
    12. MsgBox(CInt(tb_files.Lines.Length))
    13. ProgressBar_Ges.Maximum = lin
    14. ProgressBar_Ges.Value = 0
    15. For Each line As String In tb_files.Lines
    16. If Not BGW.IsBusy Then
    17. BGW.RunWorkerAsync(line)
    18. End If
    19. Next
    20. End If
    21. End Sub
    22. Private Sub BGW_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BGW.DoWork
    23. wc.Proxy = Nothing
    24. wc.DownloadFileAsync(New Uri("http://scarecoding.ohost.de/asynctest/" + e.Argument), Application.StartupPath + "/" + e.Argument)
    25. End Sub
    26. Private Sub BGW_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BGW.ProgressChanged
    27. End Sub
    28. Private Sub BGW_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BGW.RunWorkerCompleted
    29. Label1.Text = "Download abgeschlossen"
    30. End Sub
    31. Private Sub wc_DownloadProgressChanged(sender As Object, e As Net.DownloadProgressChangedEventArgs) Handles wc.DownloadProgressChanged
    32. Invoke(Sub()
    33. ProgressBar_File.Maximum = CInt(e.TotalBytesToReceive)
    34. ProgressBar_File.Value = CInt(e.BytesReceived)
    35. End Sub)
    36. End Sub
    37. End Class


    Ich der tb_files steht das hier:

    Quellcode

    1. 1.txt
    2. 2.txt
    3. 3.txt
    4. 4.txt


    Ich möchte eigentlich das es mir eine Datei nach der anderen von meinem Webspace herunterlädt und mit den Gesamt und auch den Momentan Fortschritt anzeigt ein den beiden ProgressBar's.

    Die "1.txt" wird heruntergeladen und der Aktuelle Fortschritt wird mir richtig angezeigt. aber die 2 3 & 4.txt werden nicht heruntergeladen, ich weis nicht wie ich das machen muss das der BGW wartet bis die eine Datei fertig geladen wurde und dann die nächste nimmt.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „.Scare“ ()

    Wenn Du mit

    .Scare schrieb:

    VB.NET-Quellcode

    1. DownloadFileAsync
    Dateien ziehst, brauchst Du keinen BGW, denn das Async sorgt bereits dafür, dass das Downloaden in einem anderen Thread stattfindet.
    Falls Du mehrere Dokumente parallel downloaden willst, gugst Du hier.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Danke für deine Rasche AW, ich habe es auch schon versucht ohne BGW, aber wen ich dann mehrere Dateien habe wie in diesem Fall kommt immer ein Fehler das der Downloader bereits was macht. Ich möchte nur eine Datei nach der anderen herunterladen, dies aber mit der Async Methode da ich auf die weise den Fortschritt der einzelnen Dateien ausgeben könnte.

    was ja mit dem normalen DownloadFile nicht geht. deshalb dachte ich mit dem BGW könnte es gehen.

    mein Vorhaben:

    Liste mit Dateien erstellen
    überprüfen ob vorhanden
    wen nicht ---> Herunterladen
    fertig.

    es sind in der regel 300-700 Dateien in einer Grössen von ca. 1Mb-50Mb

    .Scare schrieb:

    mehrere Dateien
    musst Du pro Datei einen neuen DownloadFileAsync starten.
    Gugst Du nochmal hier, lies das mal bis zum Ende durch.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hm ich steige nicht ganz durch bei deinem Code was da ganz genau abgeht. und warum das du dies mit Threads machst und immer wider neue Threads erstellst?

    Gibt es nicht eine einfachere Lösung? Das ich die Dateien in einer ForEach Schleife abarbeiten kann und so an eine Sub Schicke welche sie dann herunterlädt?
    Ich möchte nicht unbedingt zuviel mit Threads machen da ich diese noch nicht sooo gut kenne und weis das man da viele Fehler reinhauen kann und gut aufpassen muss wegen den Zugriffen aus einem Thread heraus.

    :)

    EDIT: Sowas dachte ich mir <<----Klick
    @.Scare
    Willst Du die Files nacheinander downloaden
    oder
    willst Du die Files parallel downloaden?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    @.Scare
    Willst Du die Files nacheinander downloaden
    oder
    willst Du die Files parallel downloaden?




    eines nach dem anderen, aber mit Fortschritts Anzeige für das ladende File und für den Gesamtzustand.


    ich überprüfe die Datei in einer schleife, wen OK weiter. wen nicht oke --> Download.. DL fertig weiter prüfen.

    Sorry das ich es nicht so ganz verständlich rüber gebracht habe.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „.Scare“ ()

    wüsste hier jemand eine Lösung zu meinem Problem?

    Nochmals eine kleine schilderung:

    Ich versuche es mehrere Dateien zu Downloaden, eine Datei nach der anderen und dies mit DownloadFileAsync
    weil ich mit 2 Progressbars Arbeiten möchte(Aktueller Fortschritt, Gesamtfortschritt)

    Das Problem ist das ich nicht drauf komme wie das ich dem Downloader sagen kann das er warten soll mit der nächsten Datei solange noch die Vorige am herunterladen ist.
    dies ist auch bekannt. alle Dateien stehen in einer liste. durch das kann ich einen ladebalken für den gesammt Fortschritt machen.Mein Problem bezieht sich aber auf das mit dem DownloadFileAsync mit DownloadFile geht es, aber da kann ich den Aktuellen Fortschritt nicht an eine PB geben.

    deswegen möchte ich es mit DownloadFileAsync realisieren.

    ErfinderDesRades schrieb:

    ja, gut, da musste halt eine Ereigniskette programmieren.
    Es gibt ja das DownlaodCompleted -Event, und darin musste halt den nächsten Download starten.


    hm da liegt ja grad mein Problem, ich arbeite die liste mit einer For Each Schleife ab. Wie kann ich dem dann eine solche ereignisskete geben? dies geht mir nicht so ganz in die "Birne" :)

    VB.NET-Quellcode

    1. For Each line As String In tb_files.Lines
    2. Downloader(line)
    3. Next


    ErfinderDesRades schrieb:

    Was jdfs. nicht geht ist, Backgroundworker und DownloadAsync gleichzeitig einzusetzen.

    Dies Dachte ich mir auch schon fast. hatte die Hoffnung das ich dies beim BGW realisieren könnte, das er wartet bis der DL fertig ist und dann den nächsten DL startet.


    __________________________________________________________________________________________________________________________

    Mein Bisheriger Code ist so:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Dim WithEvents wc As New System.Net.WebClient
    3. Public link As String = ("http://scarecoding.ohost.de/asynctest/")
    4. Public loc_path As String = Application.StartupPath + "/"
    5. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    6. 'Anzahl Zeilen
    7. Dim Zeilen() As String
    8. Zeilen = Split(tb_files.Text, vbCrLf)
    9. Dim Anzahl_Linien As Integer = CInt(UBound(Zeilen))
    10. '##################################################
    11. Label1.Text = "Download wird gestartet"
    12. Button1.Enabled = False
    13. ProgressBar_Ges.Maximum = Anzahl_Linien
    14. ProgressBar_Ges.Value = 0
    15. For Each line As String In tb_files.Lines
    16. Downloader(New Uri(link & line), loc_path + line)
    17. Next
    18. End Sub
    19. Private Sub Downloader(ByVal link As Uri, ByVal loc_path As String)
    20. wc.Proxy = Nothing
    21. wc.DownloadFileAsync(link, loc_path)
    22. End Sub
    23. Private Sub wc_DownloadFileCompleted(sender As Object, e As System.ComponentModel.AsyncCompletedEventArgs) Handles wc.DownloadFileCompleted
    24. ProgressBar_Ges.Value += 1
    25. End Sub
    26. Private Sub wc_DownloadProgressChanged(sender As Object, e As Net.DownloadProgressChangedEventArgs) Handles wc.DownloadProgressChanged
    27. Invoke(Sub()
    28. ProgressBar_File.Maximum = CInt(e.TotalBytesToReceive)
    29. ProgressBar_File.Value = CInt(e.BytesReceived)
    30. End Sub)
    31. End Sub
    32. End Class


    Aber genau hier ist das Problem das die Schleife schneller ist als der WebClient Nun müsste ich irgend wie sagen können das der Nächste Download erst beginnt wen der Vorige fertig ist... nur wie?

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „.Scare“ ()

    hmm.. habe ich richtig verstanden...
    du willst.. sagen wir 5 Dateien herunter laden.
    und eine "Downloadanzeige" haben die z.b. anzeigt wieviele der 5 Files fertig sind.
    (also nicht die Länge der File sondern einfach die Anzahl?

    warum dann fileasync?
    mache einen BGW und lasse dort deine schleife mit den 5 files abarbeiten. und nach jeder fertigen Datei,
    (er kommt ja erst zurück wenn er fertig ist), dann die Dateianzeige eins rauf.
    ferddich..

    oder wie EDR schon sagte.. auf das complete-Event warten.
    Hallo,

    Nein ich möchte 2 Ladebalken haben.. einen für das Gesamte also anzahl Files und einen für den Momentanen Fortschritt des gerade ladenden Files

    RoulettePilot schrieb:

    oder wie EDR schon sagte.. auf das complete-Event warten.


    ja, nur genau DAS ist genau das was ich suche aber nicht finde.. wie kann ich WARTEN? ich möchte unbedingt den Async benutzen.

    Hier nochmals der Code:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Dim WithEvents wc As New System.Net.WebClient
    3. Public link As String = ("http://scarecoding.ohost.de/asynctest/")
    4. Public loc_path As String = Application.StartupPath + "/"
    5. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    6. 'Anzahl Zeilen
    7. Dim Zeilen() As String
    8. Zeilen = Split(tb_files.Text, vbCrLf)
    9. Dim Anzahl_Linien As Integer = CInt(UBound(Zeilen))
    10. '##################################################
    11. Label1.Text = "Download wird gestartet"
    12. Button1.Enabled = False
    13. ProgressBar_Ges.Maximum = Anzahl_Linien
    14. ProgressBar_Ges.Value = 0
    15. For Each line As String In tb_files.Lines
    16. Downloader(New Uri(link & line), loc_path + line)
    17. Next
    18. End Sub
    19. Private Sub Downloader(ByVal link As Uri, ByVal loc_path As String)
    20. wc.Proxy = Nothing
    21. wc.DownloadFileAsync(link, loc_path)
    22. End Sub
    23. Private Sub wc_DownloadFileCompleted(sender As Object, e As System.ComponentModel.AsyncCompletedEventArgs) Handles wc.DownloadFileCompleted
    24. ProgressBar_Ges.Value += 1
    25. End Sub
    26. Private Sub wc_DownloadProgressChanged(sender As Object, e As Net.DownloadProgressChangedEventArgs) Handles wc.DownloadProgressChanged
    27. Invoke(Sub()
    28. ProgressBar_File.Maximum = CInt(e.TotalBytesToReceive)
    29. ProgressBar_File.Value = CInt(e.BytesReceived)
    30. End Sub)
    31. End Sub
    32. End Class


    nun sollte ich ja in der For Each schleife warten können oder im Downloader SUB.. und genau dies macht mir schwirigkeiten.. WIER kann ich auf das ​DownloadFileCompleted event warten?
    Du hast doch oben Stehen...
    dim WithEvents WC....

    nun wähle einfach oben links in der Combobox WC aus , und schau in der Rechten nach, was du alles für tolle Events hast, die abgefeuert werden.

    oder habe ich jetzt total was falsch verstanden?
    Schau mal den Code an den ich gepostet habe im Spoiler :)

    Ich habe das ​wc_DownloadProgressChanged && ​wc_DownloadFileCompleted ja in gebrauch.... =)

    Mein Problem ist, das der WebClient eine datei anfängt runter zu laden und dan gleich die nächste runterladen möchte.

    ICH möchte aber das er wartet bis die erste fertig ist und erst dan mit der nächsten datei weiter macht.
    dann pfeiff doch auf deine Schleife, sondern fange die nächste Datei erst dann an, wenn "completed" ist.
    also nicht nur die Progressbar +1 ,
    sondern hier auch den nächsten Load anstoßen.
    Also im Prinzip so wie du es auch sagst: Wenn fertig (Event completed) dann erst nächste Datei....

    RoulettePilot schrieb:

    Also im Prinzip so wie du es auch sagst: Wenn fertig (Event completed) dann erst nächste Datei...


    hehe.. und genau das ist mein Problem.. wie soll ich dies angehen?

    EDIT:

    Zudem kann ich auf die schleife ja nicht verzichten.. ich habe ja mehrere dateien in einer Liste stehen die es herunterladen soll...

    Ohne schleiffe kann ich dies ja nicht machen
    wie? tippen?
    :)
    mach doch eine Liste mit deinen Files..
    Setze den Zeiger auf das 1. file..
    nun downlaod starten..

    im CompleteEvent entweder Zeiger+1 und nächstes downloaden,
    oder ein Flag setzen "juuhuuuIchBinFertig" = True.. die du dann ausserhalb abfragst.
    Sobald dieses Flag True setzt du es wieder auf False und lädst die nächste Datei...
    es sei denn das Ende der Liste ist erreicht... dann machst du halt nix mehr.

    *verwirrtgugg* :)

    RoulettePilot schrieb:

    mach doch eine Liste mit deinen Files..


    meinst du eine List of?

    RoulettePilot schrieb:

    Setze den Zeiger auf das 1. file..

    Wie setze ich den Zeiger auf das erste File? =) Heute ist wirklich grad etwas verwirrungs Tag =))))

    Danke für deine Hilfsbereitschaaft =)

    EDIT:

    Ich glaube ich habe durch deine Inspiration eine Idee was und wie du es meinst. mal testen =)