DownloadfileAsync richtig anwenden
lima-city → Forum → Programmiersprachen → Programmieren mit .NET & Mono
agent
artist
bestimmen
code
double
download
file
funktion
item
match
pfad
problem
schleife
sender
setting
string
system
tag
text
weben
-
Hallo zusammen,
Ich habe hier eine kleine tag/funktion">Funktion:
Private Sub DownloadFile(file As String, pfad As String) AddHandler Web.DownloadFileCompleted, AddressOf Downloadfile_complete AddHandler Web.DownloadProgressChanged, AddressOf Downloadfile_progress Web.Headers("User-Agent") = "Mozilla/4.0" Web.Proxy = Nothing Web.DownloadFile(New Uri(file), pfad) End Sub Private Sub Downloadfile_progress(sender As Object, e As DownloadProgressChangedEventArgs) Me.ToolStripProgressBar1.Value = e.ProgressPercentage lblPercentage.Text = e.ProgressPercentage & "%" Dim totalbytes As Double = Math.Round(e.TotalBytesToReceive / 1024 / 1024, 1) Dim bytes As Double = Math.Round(e.BytesReceived / 1024 / 1024, 1) lblKB.Text = bytes & "\" & totalbytes & "MB" End Sub Private Sub Downloadfile_complete(sender As Object, e As ComponentModel.AsyncCompletedEventArgs) Web.Dispose() If My.Settings.OriginalFile = My.Settings.SuggestedFile Then DownloadAlbumArt() Else ConvertFile() End If 'Dim sourcecode As String = WebBrowser.DocumentText.ToString 'Dim artist As String, app As String, title As String ''Titel und App bestimmen 'Try ' Dim Rgx As New System.Text.RegularExpressions.Regex("<META content=\047\042(?<title>.*)\042 on (?<App>.*) from Smule\047 property=\042og\072title\042>") ' Dim Match = Rgx.Match(sourcecode) ' title = Match.Groups("title").Value ' app = Match.Groups("App").Value 'Catch ex As Exception ' title = "Unknown" ' app = "Unknown" 'End Try ''Artist bestimmen 'Try ' 'Example Line <meta name="twitter:title" content='""Apologize" on Magic Piano" performed by MarvinKleinMusic"> ' Dim webtitle As String = sourcecode.Split({"""handle"":"""}, StringSplitOptions.None)(1).Split({""}, StringSplitOptions.None)(CInt(("0"))) ' Dim TestArray() As String = Split(webtitle, """") ' artist = TestArray(0) 'Catch ex As Exception ' artist = "Unknown" 'End Try 'Dim MP3FilePath As New TagLib.File.LocalFileAbstraction(My.Settings.OriginalFile) 'Dim MP3File As TagLib.File = TagLib.File.Create(MP3FilePath) ''ID3 Tags schreiben 'MP3File.Tag.Album = app 'MP3File.Tag.Title = title 'MP3File.Tag.Performers = New String() {artist} 'MP3File.Save() 'MP3File.Dispose() End Sub
Ansich funktioniert sie auch prima. Allerdings wenn man diese Funktion mit einer Schleife aufruft um mehrere Dateien hintereinander runterzuladen gibt es eine Exception.
Eine nicht behandelte Ausnahme des Typs "System.NotSupportedException" ist in System.dll aufgetreten.
Zusätzliche Informationen: WebClient unterstützt keine gleichzeitigen E/A-Vorgänge.
Wie wende ich DownloadfileAsync nun richtig an, sodass es funktioniert?
Hier nochmal die Schleife, die die Downloads starten soll:
For i As Integer = ListView1.Items.Count - 1 To 0 Step -1 DownloadFile(ListView1.Items(i).SubItems(1).Text, ListView1.Items(i).Text.ToString) Next
Mein Zielframework ist 4.0
Liebe Grüße -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Du rufst die Funktion "DownloadFile" mehrmals auf.
Dann wird auch mehrmals die Funktion "Downloadfile_complete" aufgerufen und dort wird die Variable Web disposed und ich sehe nicht dass diese Web Variable pro Aufruf neu erstellt wird.
Könnte das vielleicht der Fehler sein?
Was passiert wenn du 2x eine Datei runterlädst aber nicht in Schleife sondern nachdem der 1te Download abgeschlossen ist?
Gruß -
Nachdem der erste Download abgeschlossen ist, lassen sich problemlos weitere Dateien runterladen.
Nur die For Schleife für automatische Downloads sorgt für das Problem.
LG -
und Web.Dispose() verursacht keine Probleme?
weil das ist beim 2ten Aufruf nicht mehr vorhanden so weit ich das sehe
Gruß -
Web.Dispose() hat keinerlei Probleme verursacht. Die Exception bezieht sich auf die DownloadfileAsync Zeile.
Das Problem was ich genau habe ist, dass die For Schleife zwar alle Items abarbeitet, allerdings direkt hintereinander ohne abzuwarten, das beim ersten Durchgang die Funktion komplett ausgeführt wurde.
Wenn ich meinen Code nun relativ einfach veränder,
Private Sub DownloadFile(file As String, pfad As String) Using Web As New WebClient() AddHandler Web.DownloadFileCompleted, AddressOf Downloadfile_complete AddHandler Web.DownloadProgressChanged, AddressOf Downloadfile_progress Web.Headers("User-Agent") = "Mozilla/4.0" Web.Proxy = Nothing Web.DownloadFileAsync(New Uri(file), pfad) My.Settings.wait = True End Using End Sub
funktionieren zwar mehrere Downloads. Allerdings stören die sich gegenseitig in den AddHandlern und sorgen dafür, dass die Progressbar sowie das lblKB immer falsch dargestellt wird.
Ich suche also einen Weg die For Schleife erst zu wiederholen, wenn Downloadfile_complete ausgeführt wurde.
LG
Beitrag zuletzt geändert: 28.9.2015 19:54:38 von marvinkleinmusic -
Bau ein If ein und bei bedarf dann mit
Continue For
arbeiten
Oder arbeite mit Variablen so dass es keine Zusammenstöße gibt. Das ganze dann vielleicht in einer Function auslagern um es mit Variablen ausführen zu lassen
Beitrag zuletzt geändert: 28.9.2015 21:07:06 von duxaquila -
Könntest du mir dafür ein Beispiel geben? Meins funktioniert nicht xD
For i As Integer = ListView1.Items.Count - 1 To 0 Step -1 DownloadFile(ListView1.Items(i).SubItems(1).Text, ListView1.Items(i).Text.ToString) If My.Settings.wait = False Then Continue For Next
-
Ich hab mir mal das ganze angeschaut.
Frage :) Hast du irgendwo vermerkt dass DownloadFile = DownloadFileAsync sein solle? Falls nein nutzt du nur DownloadFile und msdn sagt
NotSupportedException
Die Methode wurde gleichzeitig für mehrere Threads aufgerufen.
Da du diesen Fehler hast und es bei DownloadFileAsync diese "Ausnahme" nicht gibt gehe ich stark davon aus das du Async nicht nutzt ;)
Private Sub DownloadFileAsync(file As String, pfad As String) Web.Headers("User-Agent") = "Mozilla/4.0" Web.Proxy = Nothing Web.DownloadFileAsync(New Uri(file), pfad) End Sub Private Sub Downloadfile_progress(sender As Object, e As DownloadProgressChangedEventArgs) Me.ToolStripProgressBar1.Value = e.ProgressPercentage lblPercentage.Text = e.ProgressPercentage & "%" Dim totalbytes As Double = Math.Round(e.TotalBytesToReceive / 1024 / 1024, 1) Dim bytes As Double = Math.Round(e.BytesReceived / 1024 / 1024, 1) lblKB.Text = bytes & "\" & totalbytes & "MB" End Sub Private Sub Downloadfile_complete(sender As Object, e As ComponentModel.AsyncCompletedEventArgs) Web.Dispose() If My.Settings.OriginalFile = My.Settings.SuggestedFile Then DownloadAlbumArt() Else ConvertFile() End If 'Dim sourcecode As String = WebBrowser.DocumentText.ToString 'Dim artist As String, app As String, title As String ''Titel und App bestimmen 'Try ' Dim Rgx As New System.Text.RegularExpressions.Regex("<META content=\047\042(?<title>.*)\042 on (?<App>.*) from Smule\047 property=\042og\072title\042>") ' Dim Match = Rgx.Match(sourcecode) ' title = Match.Groups("title").Value ' app = Match.Groups("App").Value 'Catch ex As Exception ' title = "Unknown" ' app = "Unknown" 'End Try ''Artist bestimmen 'Try ' 'Example Line <meta name="twitter:title" content='""Apologize" on Magic Piano" performed by MarvinKleinMusic"> ' Dim webtitle As String = sourcecode.Split({"""handle"":"""}, StringSplitOptions.None)(1).Split({""}, StringSplitOptions.None)(CInt(("0"))) ' Dim TestArray() As String = Split(webtitle, """") ' artist = TestArray(0) 'Catch ex As Exception ' artist = "Unknown" 'End Try 'Dim MP3FilePath As New TagLib.File.LocalFileAbstraction(My.Settings.OriginalFile) 'Dim MP3File As TagLib.File = TagLib.File.Create(MP3FilePath) ''ID3 Tags schreiben 'MP3File.Tag.Album = app 'MP3File.Tag.Title = title 'MP3File.Tag.Performers = New String() {artist} 'MP3File.Save() 'MP3File.Dispose() End Sub
For i As Integer = ListView1.Items.Count - 1 To 0 Step -1 DownloadFileAsync(ListView1.Items(i).SubItems(1).Text, ListView1.Items(i).Text.ToString) Next
Natürlich ungetestet :) Sitz an einen Linux rechner :D
p.S. das was ich mich grade frage, wird " Private Sub Downloadfile_complete(sender As Object, e As ComponentModel.AsyncCompletedEventArgs)" richtig aufgerufen?
Beitrag zuletzt geändert: 28.9.2015 22:07:10 von duxaquila -
Natürlich verwende ich Async :D
Downloadfile ist bloß der Name des Subs der aufgerufen wird.
Private Sub DownloadFile(file As String, pfad As String) 'Subname Using Web As New WebClient() AddHandler Web.DownloadFileCompleted, AddressOf Downloadfile_complete AddHandler Web.DownloadProgressChanged, AddressOf Downloadfile_progress Web.Headers("User-Agent") = "Mozilla/4.0" Web.Proxy = Nothing Web.DownloadFileAsync(New Uri(file), pfad) 'Async My.Settings.wait = True End Using End Sub
EDIT:/
Wenn ich Downloadfile verwende statt Async, lädt er alles runter, jedoch freezt das Programm, bis alle Downloads abgeschlossen sind.
Beitrag zuletzt geändert: 28.9.2015 22:08:37 von marvinkleinmusic -
Du verwendest also "DownloadFile" als "DownloadFileAsync" Oben anhand deines Codes war dieses nicht ersichtlich.
Meinst du nicht das dieses Muster eher Subobtimal ist?
Ich weiß nicht was so alles neu ist aber "AddHandler" musste ich nicht angeben damals um "DownloadFileCompleted" aufzurufen
Schau dir das mal abn vielleicht wirst du daraus schlau ;)
Dim WithEvents myWebClient As New Web Private Sub Downloadfile_progress(sender As Object, e As DownloadProgressChangedEventArgs) Me.ToolStripProgressBar1.Value = e.ProgressPercentage lblPercentage.Text = e.ProgressPercentage & "%" Dim totalbytes As Double = Math.Round(e.TotalBytesToReceive / 1024 / 1024, 1) Dim bytes As Double = Math.Round(e.BytesReceived / 1024 / 1024, 1) lblKB.Text = bytes & "\" & totalbytes & "MB" End Sub Private Sub Downloadfile_complete(sender As Object, e As ComponentModel.AsyncCompletedEventArgs) Web.Dispose() If My.Settings.OriginalFile = My.Settings.SuggestedFile Then DownloadAlbumArt() Else ConvertFile() End If 'Dim sourcecode As String = WebBrowser.DocumentText.ToString 'Dim artist As String, app As String, title As String ''Titel und App bestimmen 'Try ' Dim Rgx As New System.Text.RegularExpressions.Regex("<META content=\047\042(?<title>.*)\042 on (?<App>.*) from Smule\047 property=\042og\072title\042>") ' Dim Match = Rgx.Match(sourcecode) ' title = Match.Groups("title").Value ' app = Match.Groups("App").Value 'Catch ex As Exception ' title = "Unknown" ' app = "Unknown" 'End Try ''Artist bestimmen 'Try ' 'Example Line <meta name="twitter:title" content='""Apologize" on Magic Piano" performed by MarvinKleinMusic"> ' Dim webtitle As String = sourcecode.Split({"""handle"":"""}, StringSplitOptions.None)(1).Split({""}, StringSplitOptions.None)(CInt(("0"))) ' Dim TestArray() As String = Split(webtitle, """") ' artist = TestArray(0) 'Catch ex As Exception ' artist = "Unknown" 'End Try 'Dim MP3FilePath As New TagLib.File.LocalFileAbstraction(My.Settings.OriginalFile) 'Dim MP3File As TagLib.File = TagLib.File.Create(MP3FilePath) ''ID3 Tags schreiben 'MP3File.Tag.Album = app 'MP3File.Tag.Title = title 'MP3File.Tag.Performers = New String() {artist} 'MP3File.Save() 'MP3File.Dispose() End Sub 'Dein Event was DownloadFileAsync auslöst Web.DownloadFileAsync(ListView1.Items(i).SubItems(1).Text, ListView1.Items(i).Text.ToString)
Zur not schau dir mal https://github.com/DuxAquila/Launcher_VB/blob/master/Launcher%20VB/Addons.vb das an ist alt aber geht -
Das hilft mir leider alles nicht weiter. Das bezieht sich ebenfalls nur auf einen Download am Stück.
Mein Problem ist aber das meine For Schleife zwar funktioniert, allerdings nicht abwartet bis meine Funktion beendet ist.
Dadurch das ich im Code nun definiert habe, dass er Web immer als neuen Webclient benutzen soll, funktioniert es zwar mit den Downloads, allerdings werden diese gleichzeitig runtergeladen und beeinflussen dadurch alle gegenseitig mein ProgressChanged und Complete Event.
Ich suche halt wie bereits gesagt einen Weg die Downloads zu starten sobald der aktuell laufende Download abgeschlossen wurde.
LG -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage