BakgroundWorker und DownloadFileAsync

  • VB.NET

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

    Du denkst zu sequenziell, asynchrone Operationen geschehen aber immer eventbasiert.
    Du beginnst damit, dass du die erste Datei aus der Liste downloadest, dann machst du erst mal gar nichts mehr. Sobald dann DownloadFileCompletet ausgelöst wird, downloadest du die zweite Datei und mehr nicht. Wird jetzt wieder DownloadFileCompleted ausgelöst, downloadest du die dritte Datei und immer so weiter, bis es keine Dateien mehr in der Liste gibt.
    hmm.. nanü?
    also eine Liste erstellen, z.B. dim MyListe as new list (of String)
    und einen "Zeiger" also dim Zeiger as integer=0
    wo deine schleife ist anstatt : downloader ( new uri...
    schreibst myliste.add (line)

    nach deiner scheife..
    rufst du EINMAL den Downloader auf.
    Zeiger+=1
    downlaoder ( new uri.... myliste(zeiger-1)....... usw.

    hier ende...

    im completevent..
    if Zeiger >= myliste.. then Exit Sub .. ferddich..
    sonst
    Zeiger+=1
    downlaoder ( new uri.... myliste(zeiger-1)....... usw.
    end sub
    Danke euch beiden, so dachte ich es mir auch gerade durch eure Hilfe. Mal sehen ob ich dies in mein Code Geschnetzel hinein bekomme =)

    ____________________________________________________________________________________________________________

    EDIT:

    So es scheint alles zu gehen, nochmals danke an : @RoulettePilot & @Artentus

    Damit Alle etwas davon haben stelle ich euch gerne den Code auch noch hier hin.

    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://*********************t.de/asynctest/")
    4. Public loc_path As String = Application.StartupPath + "/"
    5. Public Download_list As New List(Of String)
    6. Public zähler As Integer = 0
    7. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    8. 'Anzahl Zeilen
    9. Dim Zeilen() As String
    10. Zeilen = Split(tb_files.Text, vbCrLf)
    11. Dim Anzahl_Linien As Integer = CInt(UBound(Zeilen))
    12. '##################################################
    13. Label1.Text = "Download wird gestartet"
    14. Button1.Enabled = False
    15. ProgressBar_Ges.Maximum = Anzahl_Linien + 1
    16. ProgressBar_Ges.Value = 0
    17. For Each line As String In tb_files.Lines
    18. Download_list.Add(line)
    19. Next
    20. Downloader(New Uri(link & Download_list(zähler)), loc_path + Download_list(zähler))
    21. End Sub
    22. Private Sub Downloader(ByVal link As Uri, ByVal loc_path As String)
    23. wc.Proxy = Nothing
    24. wc.DownloadFileAsync(link, loc_path)
    25. End Sub
    26. Private Sub wc_DownloadFileCompleted(sender As Object, e As System.ComponentModel.AsyncCompletedEventArgs) Handles wc.DownloadFileCompleted
    27. lb_percent.Text = "Abgeschlossen"
    28. ProgressBar_Ges.Value += 1
    29. zähler += 1
    30. If Not zähler >= Download_list.Count Then
    31. Downloader(New Uri(link & Download_list(zähler)), loc_path + Download_list(zähler))
    32. End If
    33. End Sub
    34. Private Sub wc_DownloadProgressChanged(sender As Object, e As Net.DownloadProgressChangedEventArgs) Handles wc.DownloadProgressChanged
    35. Invoke(Sub()
    36. ProgressBar_File.Maximum = CInt(e.TotalBytesToReceive)
    37. ProgressBar_File.Value = CInt(e.BytesReceived)
    38. lb_percent.Text = e.ProgressPercentage & "%"
    39. End Sub)
    40. End Sub
    41. End Class​

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

    *g* EINEN hab ich noch...
    Ich hoffe ich verwirre dich jetzt nicht noch zusätzlich, falls ja, ignoriere dieses hier

    nimm keinen Zeiger.. sondern nur die Liste.
    Lade immer den ersten Eintrag, und lösche ihn dann
    myDownloadfile = myliste(0)
    myliste.removeat(0)
    downlaoder (.... mydownloadfile)


    im completeEvent fragst du dann nur ab, ob die liste endlich leer ist..
    if myliste.Count=0 then Exit Sub.. ferddich...
    ansonsten:
    myDownloadfile = myliste(0)
    myliste.removeat(0)
    downlaoder (.... mydownloadfile)

    Das hat den Vorteil, das du nix doppelt gemoppelt hast, und während dem Download noch neue Dateien hinzufügen kannst.
    (Nur so eine Idee.. wie immer fällt einem sowas immer hinterher ein)

    Edit.. Huch.. zu spät :)
    Fand es als Herausforderung das nachzubauen.
    Voraussetzung: Form1
    Button1:Start Download
    Button2:Abbruch
    ProgressBarAll: Gesamtfortschritt / Maxvalue = 100
    ProgressBarFile: File Download Fortschritt / Maxvalue = 100

    Tipp: Da die Filegrößen der Bytes jenseits vom Überlauf von Integer liegen (ProgressBar.Value etc), arbeiten meine Progressbars mit Prozent!

    Und hier ist meine getestete und fertige Lösung dafür
    8-) ...
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Net
    2. Imports System.ComponentModel
    3. Public Class Form1
    4. Private AllesInOrdnung As Boolean
    5. Public Event DownloadAbgeschlossen(ByVal Abgebrochen As Boolean)
    6. Private WithEvents WC As New WebClient
    7. ' DOWNLOAD FORTSCHRITT...
    8. Private Sub WC_DownloadProgressChanged(sender As Object, e As DownloadProgressChangedEventArgs) Handles WC.DownloadProgressChanged
    9. ' File mit Byte Länge 0 (solls ja geben), würde Division/0 Fehler produzieren...
    10. If e.TotalBytesToReceive > 0 Then
    11. Dim EinProzent As Double = e.TotalBytesToReceive / 100
    12. Dim Fortschritt As Integer = CInt(Math.Round(e.BytesReceived / EinProzent, 0))
    13. ProgressBarFile.Value = Fortschritt
    14. End If
    15. Application.DoEvents()
    16. End Sub
    17. ' DOWNLOAD COMPLETE...
    18. Private Sub WC_DownloadFileCompleted(sender As Object, e As AsyncCompletedEventArgs) Handles WC.DownloadFileCompleted
    19. RaiseEvent DownloadAbgeschlossen(e.Cancelled)
    20. End Sub
    21. ' COMPLETE EVENT...
    22. Private Sub Form1_DownloadAbgeschlossen(Abgebrochen As Boolean) Handles Me.DownloadAbgeschlossen
    23. AllesInOrdnung = Not Abgebrochen
    24. End Sub
    25. ' DOWNLOAD UNTERBRECHUNG...
    26. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    27. WC.CancelAsync()
    28. End Sub
    29. ' START DOWNLOADS ...
    30. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    31. Dim sDat() As String = {"http://<adresse>/<filename1>.jpg", _
    32. "http://<adresse>/<filename2>.jpg", _
    33. "http://<adresse>/<filename3>.jpg", _
    34. "http://<adresse>/<filename4>.jpg"}
    35. ' Überlauf verhindern wenn keine Files zum Downloaden vorhanden!
    36. If Not sDat.Count > 0 Then Exit Sub
    37. ' ProgressBar Integer Aufbereitung...
    38. Dim EinProzent As Double = sDat.Count / 100
    39. ' Cancel Option Set...
    40. AllesInOrdnung = True
    41. For i As Integer = 0 To (sDat.Count - 1)
    42. ' Gesamtfortschritt:
    43. Dim Fortschritt As Integer = CInt(Math.Round((i + 1) / EinProzent, 0))
    44. ProgressBarAll.Value = Fortschritt
    45. Application.DoEvents()
    46. ' Zieldatei & Download:
    47. Dim Nach As String = "C:\Temp\" & sDat(i).Substring(sDat(i).LastIndexOf(CChar("/")) + 1)
    48. WC.DownloadFileAsync(New Uri(sDat(i)), Nach)
    49. ' Async Busy Loop:
    50. Do While WC.IsBusy
    51. Application.DoEvents()
    52. System.Threading.Thread.Sleep(250) ' Viertelsekunde warten
    53. Loop
    54. ' Cancel Check:
    55. If Not AllesInOrdnung Then Exit For
    56. Next
    57. If AllesInOrdnung Then
    58. MsgBox("done!")
    59. Else
    60. MsgBox("Download wurde unterbrochen!")
    61. End If
    62. ProgressBarAll.Value = 0
    63. ProgressBarFile.Value = 0
    64. End Sub
    65. ' CLOSE FORM...
    66. Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
    67. WC.Dispose()
    68. End Sub
    69. End Class


    Ich habe lediglich die Dateinamen der Files die gedownloaded werden sollen, geändert. Dasss muss den Bedürfdnissen angepasst werden.
    Bilder
    • download-async-form.png

      28,79 kB, 551×265, 66 mal angesehen
    @.Scare Hast Du überhaupt hier schon mal reingesehen?

    RodFromGermany schrieb:

    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!

    ErfinderDesRades schrieb:

    Dein Code ist ziemlich schlimm

    Okay, wobei ziemlich schlimm nur eins ist: 4 Zeilen, die Loop Schleife mit dem Taskwarten, bevor der Code weiter läuft.
    Das lässt sich sehr einfach ändern in eine sich selbst aurfufende Funktion, eben wie aus Post 23.

    Der Grund war der, weil ich gerade ein Programm erstelle, wo ich viele Dinge nacheinander machen muss. Und jeweils auf dessen Abschluß warten muss, bevor ich wieder im Code weiter kann. Einmal ist es Zippen, dann CopyDirectory, dann weitere Routinen. Nicht alle lösen einen Event aus, wie: "DownloadComplete". Deshalb hab ich das so angefangen. Kein Problem, Den Befehl einfach ausführen ZipFile.CreateFromDirectory, aber nicht wenn man nebenbei einen Progresszähler laufen lassen will. Da macht es also durchaus Sinn!

    Aber stimmt, dies ist mir vorher nicht aufgefallen. Nicht schön - in diesem konkreten Beispiel :P

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

    RodFromGermany schrieb:

    @.Scare Hast Du überhaupt hier schon mal reingesehen?

    RodFromGermany schrieb:

    Falls Du mehrere Dokumente parallel downloaden willst, gugst Du hier.


    Hallo EDR Ja ich habe mir dis angeschaut und durchgelesen. aber ich wollte ja auch nicht mehrere Dateien "Parallel" herunterladen. Dennoch auch dir danke für die Mühe und Hilfe.

    .Scare schrieb:

    ich wollte ja auch nicht mehrere Dateien "Parallel" herunterladen.
    Warum nicht?
    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 schrieb:

    ich wollte ja auch nicht mehrere Dateien "Parallel" herunterladen.
    Warum nicht?


    Weil manche Server dies nicht erlauben mehrere Dateien auf einmal herunter zu laden =) und weil ich gerne mit einer Progress-bar arbeite für den Aktuellen Fortschritt und einer für den Gesamt Fortschritt

    .Scare schrieb:

    und weil ich gerne mit einer Progress-bar arbeite
    Und was, wenn der Server parallel-Download erlaubt?
    Bei dem, was ich daraus gebastelt habe, habe ich 8 Progressbars parallel.
    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!
    Doch, glaub das bringt vorteile, denn beim Internet handelt es sich um ein Netz von Leitungen, und parallele Downloads werden über verschiedene Routen geroutet. Der Anschluss des End-Users ist dabei glaub meist nicht der "Flaschenhals".

    Aber sicher bin ich nicht, weil vonne Geheimnisse der Optimierungen der Netzwerkkommunikation hab ich so gut wie 0 Ahnung.

    Im Grunde wäre das jetzt ein fabelhafter Anlass, da mal ein paar Tests zu fahren.