Kleines Lausiges Problem bei Downloaden in einer For Next Schleife

  • VB.NET

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von GearTechDE.

    Kleines Lausiges Problem bei Downloaden in einer For Next Schleife

    Hallo,
    ich bin gerade dabei einen Patcher zu programmieren. Es funktioniert alles bis auf ein sooo kleines Problem -.-
    Ich habe eine Variable oben am Dokument welche ich PatchPath genannt habe.

    Also so:

    VB.NET-Quellcode

    1. Dim PatchPath As String = "http://XXXXX.de/Patch/Files/"


    So und dann hab ich eine For Next Schleife, die list.dat lade ich zuvor herunter!:

    VB.NET-Quellcode

    1. For Each line In IO.File.ReadAllLines(".\UserData\list.dat")
    2. PatchFiles.DownloadFileAsync(New Uri(PatchPath & "\" & line), line)
    3. Next


    Wenn ich das ausführe, bekomme ich einen Fehler und zwar das irgendeine Quelle nicht gefunden wurde. Leider Gottes kann ich die URI da nicht sofort als URI nehmen, weil ich sonst den & Operator nicht mehr benutzen kann etc.

    Was mir allerdings noch ein Rätsel ist, wenn ich die Datei ohne Events herunterlade also einfach so:

    VB.NET-Quellcode

    1. For Each line In IO.File.ReadAllLines(".\UserData\list.dat")
    2. PatchFiles.DownloadFile(PatchPath & "\" & line), line)
    3. Next


    wenn ich es so mache, funktioniert alles fehlerfrei, ich möchte aber das mein Download in einer Progressbar angezeigt wird und nicht im hintergrund ausgeführt wird. Wie mache ich das jetzt, hab schon X MAL alles versucht aber bin immer gescheitert.

    Könnt ihr mir helfen?
    Also..

    1.) Ich benutze einen WebClient, was auch sonst? xD
    2.) Try Catch Block? Warum sollte ich den nicht nehmen? Ja du hast recht, beim überprüfen der Version lade ich die Version runter das in einem Try Block sonst wirft der mir doch ne blöde fehlermeldung an den kopf.. aber kann das wirklich daran liegen? in der try block überprüfe ich dann noch:

    VB.NET-Quellcode

    1. If not LokalVersion = WebVersion THen
    2. PatchList.DownloadFileAsync(ListPath, ".\UserData\list.dat")
    3. end if


    dann hab ich ne sub wenn der Patchlist vorgang aktualisiert werden soll (DownloadProgressChanged) und dort wird überprüft, wenn die progressbar den wert 100 hat, fängt der mit der For Next schleife an-.- ist da was falsch dran?

    Hier meine komplete Form

    VB.NET-Quellcode

    1. Public Class MainForm
    2. 'WebClients
    3. WithEvents PatchList As New Net.WebClient
    4. WithEvents PatchFiles As New Net.WebClient
    5. 'Versionsdaten
    6. Dim VersionClient As New Net.WebClient
    7. Dim LokalVersion As String
    8. Dim Reader As New IO.StreamReader(".\UserData\PatchVersion.dat")
    9. Dim WebVersion As String
    10. Dim VersionsLink As String = "http://XXX/Patch/PatchVersion.dat"
    11. 'Patchlist daten
    12. Private ListPath As New Uri("http://XXX/Patch/list.dat")
    13. 'Patch Ordner
    14. Dim PatchPath As String = "http://XXX/Patch/Files/"
    15. Private Sub MainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    16. Try
    17. WebVersion = VersionClient.DownloadString(VersionsLink)
    18. LokalVersion = Reader.ReadLine()
    19. Reader.Close()
    20. If Not WebVersion = LokalVersion Then
    21. LB_local.Text = LokalVersion
    22. LB_Web.Text = WebVersion
    23. PatchList.DownloadFileAsync(ListPath, ".\UserData\list.dat")
    24. Else
    25. btn_start.Enabled = True
    26. LB_local.Text = LokalVersion
    27. LB_Web.Text = WebVersion
    28. ProgressBar.Value = 100
    29. lb_status.Text = "Bereit!"
    30. End If
    31. Catch ex As Exception
    32. MsgBox("Ein Fehler ist aufgetreten, bitte kontaktiere den Administrator!", MsgBoxStyle.Critical, Title:="Error Code: 1")
    33. End
    34. End Try
    35. End Sub
    36. Private Sub PatchList_DownloadProgressCompleted(ByVal sender As Object, ByVal e As System.Net.DownloadProgressChangedEventArgs) Handles PatchList.DownloadProgressChanged
    37. ProgressBar.Value = e.ProgressPercentage
    38. lb_status.Text = "Lade 'list.dat' (" & e.ProgressPercentage & "%" & ")"
    39. If ProgressBar.Value = 100 Then
    40. lb_status.Text = "Fertig, warte auf Befehl..."
    41. For Each line In IO.File.ReadAllLines(".\UserData\list.dat")
    42. PatchFiles.DownloadFileAsync(New Uri(PatchPath & "\" & line), line)
    43. Next
    44. lb_status.Text = "Der Patchvorgang wurde erfolgreich abgeschlossen."
    45. btn_start.Enabled = True
    46. End If
    47. End Sub
    Tja - ist zwar abenteuerlich im DownloadCompleted weitere Downloads zu starten, die ja ebenfalls iwann wieder im DownLoadCompleted ankommen werden, aber warum die eigliche Schleife keinen Fehler wirft, versteh ich auch nicht.

    Dein TryCatch in der anneren Methode sollteja zum Zeitpunkt des DownloadCompletes längst durch sein.

    Tückisch auch, dass deine Handler-Methode zwar "PatchList_DownloadProgressCompleted" heißt, aber sie behandelt das ProgressChanged-Event.

    kannst höchstens mal probieren, den Vielfach-Download auf einen Test-Button-Click zu legen, ob dann die korrekte Exception kommt.
    ich kann dir fehlerzeile und so nicht sagen weil im vordergrund das mit der ausnahme steht und im hintergrund sich ne neue seite öffnet mit irgendwelchen quellen die nicht gefunden worden oder so was



    Edit: Ich habe gerade nochmal nen neues Projekt aufgemacht, wo ich alles nochmal übersichtlicher habe. da hab ich nen button erstellt und dort die schleife reinkopiert. dann hat er mir gesagt das keine gleichzeitigen E/A vorgänge erlaubt sind. dann hab ich was gegoogelt und nachgeguckt was es bedeutet und dann hab ich 2 möglichkeiten gefunden. für jede datei einen webclient anlegen oder alle nacheinander. ich habe mich für ersteres entschieden und habe ich die schleife einfach Dim PatchFiles as new Net.webclient geschrieben. Jetzt funktioniert es. Jetz wird zwar der Download im hintergrund ausgeführt, aber wie kann ich auf Events zugreifen, denn WithEvents kann ich ja nicht in der schleife benutzen?

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

    GearTechDE schrieb:

    dann hat er mir gesagt das keine gleichzeitigen E/A vorgänge erlaubt sind. dann hab ich was gegoogelt und nachgeguckt was es bedeutet und dann hab ich 2 möglichkeiten gefunden. für jede datei einen webclient anlegen oder alle nacheinander. ich habe mich für ersteres entschieden und habe ich die schleife einfach Dim PatchFiles as new Net.webclient geschrieben. Jetzt funktioniert es. Jetz wird zwar der Download im hintergrund ausgeführt, aber wie kann ich auf Events zugreifen, denn WithEvents kann ich ja nicht in der schleife benutzen?

    Jo, das ist eiglich der Fehler, wie ich ihn auch kennengelernt habe ;). Inklusive der beiden Lösungsmöglichkeiten.

    Bei viele WebClients kann man an alle denselben EventHandler hängen, mittels des AddHandler-Schlüsselwortes.

    Ich sehe nur bischen das Problem, dass du dann auch viele FortschrittsAnzeigen brauchst, denn die Downloads schreiten ja jeder in seiner eigenen Geschwindigkeit fort.
    aber ich bin ja einen patcher am programmieren der lädt nun mal alle teile nacheinander runter schon aus dem grund, weil es auch mal grössere dateien sind. ich bin momentan auch ein spiel am programmieren wo ich jetzt schon ein paar user mit beschäftige, zwar nicht mit VB sondern mit BB3D und deswegen möchte ich jetzt dafür einen patcher programmieren. ich will also alle dateien einzeln runterladen und nacheinander, und den fortschritt jeder einzelnen datei in EINER progressbar anzeigen, geht das irgendwie?
    na, das läuft ja fast auf deinen anfänglichen Code hinaus, mit dem WebClient, der in seim eigenen ProgressChanged sich selbst nochmal startet.
    Aber nicht in einer Schleife, sondern wenn die PB voll ist den jeweils nächsten.

    Das heißt, die verschiedenen urls müssen in einer Klassenvariable gespeichert werden, und jeweils eine der urls wird abgearbeitet und dann gelöscht, bis die klassenvariable leer ist.
    du brauchst eine Methode GetUris(), die die downzuloadenden urls ermittelt. Im grunde haste die ja schon, nur sollte sie den WC synchron abfahren.
    als klassenvariable eignet sich am besten eine queue(of uri), wo du mit queue.enqueue(uri) die ermittelten uris reinpackst.
    Dann eine Methode DownloadUri, die zunächst queue.Count checkt, und dann mit uri=queue.dequeue() den nächsten uri rausholt, und den webclient damit abfährt (asynchron!).
    das ProgressChanged-Event haste ja auch, dort muß bei e.ProgressValue=100 nurnoch die Methode DownloadUri wieder aufgerufen werden.
    oder gibts auch ein DownloadCompleted-Event - das wäre natürlich passender.

    wie gesagt: GetUris() sollte den WC synchron abfahren, damit die Events nicht unpassenderweise gefeuert werden, und ausserdem willst du ja den Inhalt der Info-Datei gleich verarbeiten, um die uris zu bilden.