WebClient Downloadgeschwindigkeit messen?

  • VB.NET

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von TiTo.

    WebClient Downloadgeschwindigkeit messen?

    Hallo zusammen,

    ich wollte fragen, wie ich am besten die Downloadgeschwindigkeit messen kann?

    Mittels Timer bekomme ich die restliche Zeit raus, aber beim berechnen der Geschwindigkeit sagt er "+unendkich"

    VB.NET-Quellcode

    1. sek += 1
    2. If sek > 3 Then
    3. Dim zeitproeinheit As Double = sek / download_progress.Value
    4. Dim nochzumachen As Integer = 100 - download_progress.Value
    5. Dim min As Long = 0
    6. Dim zeit As Integer = nochzumachen * zeitproeinheit
    7. If zeit > 60 Then
    8. Do Until zeit < 60
    9. zeit -= 60
    10. min += 1
    11. Loop
    12. End If
    13. If zeit < 10 Then
    14. time_lbl.Text = "Time left: " & min & ":0" & zeit & " (" & Math.Round(kb, 0) & " KB/s)"
    15. Else
    16. time_lbl.Text = "Time left: " & min & ":" & zeit & " (" & Math.Round(kb, 0) & " KB/s)"
    17. End If
    18. Else
    19. time_lbl.Text = "Calculating time..."
    20. End If

    VB.NET-Quellcode

    1. Imports System.Net ' Import auf Net
    2. Public Class Form1
    3. Dim WithEvents wc As New WebClient ' Unser WebClient
    4. Dim sw As New Stopwatch ' Stoppuhr
    5. Dim zm As Integer = 0 ' Speichert die "Zwischenmenge"
    6. Private Sub wc_DownloadProgressChanged(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs) Handles wc.DownloadProgressChanged
    7. sw.Stop() ' Stoppuhr anhalten
    8. Label1.Text = Math.Round((e.BytesReceived - zm) / 1024 / (sw.ElapsedMilliseconds / 1000)) & " KB/s" ' Berechnet die Menge
    9. ' Geladene Menge seit der letzten Änderung in Kilobytes umwandeln und durch die Anzahl Sekunden, die seit dem letzten Vorgang verstrichen sind teilen
    10. ProgressBar1.Value = e.ProgressPercentage ' Prozentwert auf die ProgressBar setzen
    11. zm = e.BytesReceived ' "Zwischenmenge" setzen
    12. sw.Restart() ' Stoppuhr neustarten
    13. End Sub
    14. Private Sub wc_DownloadFileCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs) Handles wc.DownloadFileCompleted
    15. sw.Stop() ' Wenn die Datei zu Ende geladen wurde, muss die Stoppuhr wieder gestoppt werden
    16. End Sub
    17. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    18. sw.Start() ' Stoppuhr starten
    19. wc.DownloadFileAsync(New Uri("Adresse"), "Pfad") ' Datei
    20. End Sub
    21. End Class
    Hey,

    kapsel den WebClient in einer eigenen Klasse. Gib der Klasse eine Property mit der Startzeit des Downloads. Im ProgressChanged-Event des WebClient errechnest Du die Sekunden, die seit dem Start vergangen sind und teilst die empfangenen Bytes durch diesen Wert. Kein Rumhantieren mit Timern o. ä. nötig.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    So z. B.

    VB.NET-Quellcode

    1. Imports System.Net
    2. Imports System.IO
    3. Public Class FileDownload
    4. Private WithEvents _wC As New WebClient With {.Proxy = Nothing}
    5. Private _downloadUrl As Uri
    6. Private _targetPath As DirectoryInfo
    7. Private _downloadStart As Date
    8. Public Event DownloadProgressChanged As EventHandler(Of FileDownloadProgressEventArgs)
    9. Public Event DownloadCompleted As EventHandler
    10. Public Sub New(ByVal downloadUrl As Uri, ByVal targetPath As DirectoryInfo)
    11. _downloadUrl = downloadUrl
    12. _targetPath = targetPath
    13. End Sub
    14. Public Sub DownloadFile()
    15. Dim remoteData() As String = _downloadUrl.ToString().Split("/"c)
    16. Dim remoteFile As String = remoteData(remoteData.Length - 1)
    17. _downloadStart = Now
    18. _wC.DownloadFileAsync(_downloadUrl, Path.Combine(_targetPath.FullName, remoteFile))
    19. End Sub
    20. Private Sub _wC_DownloadFileCompleted(sender As Object, e As System.ComponentModel.AsyncCompletedEventArgs) Handles _wC.DownloadFileCompleted
    21. OnDownloadComplete()
    22. End Sub
    23. Private Sub _wC_DownloadProgressChanged(sender As Object, e As DownloadProgressChangedEventArgs) Handles _wC.DownloadProgressChanged
    24. Dim secs As Integer = Convert.ToInt32((Now - _downloadStart).TotalSeconds)
    25. Dim bPerSec As Double = e.BytesReceived / secs
    26. Dim args As New FileDownloadProgressEventArgs(bPerSec, e.BytesReceived, e.TotalBytesToReceive, e.ProgressPercentage)
    27. OnProgressChanged(args)
    28. End Sub
    29. Protected Overridable Sub OnDownloadComplete()
    30. RaiseEvent DownloadCompleted(Me, EventArgs.Empty)
    31. End Sub
    32. Protected Overridable Sub OnProgressChanged(ByVal args As FileDownloadProgressEventArgs)
    33. RaiseEvent DownloadProgressChanged(Me, args)
    34. End Sub
    35. End Class
    36. Public Class FileDownloadProgressEventArgs : Inherits EventArgs
    37. Public ReadOnly bytesPerSecond As Double
    38. Public ReadOnly totalReceived As Long
    39. Public ReadOnly totalToReceive As Long
    40. Public ReadOnly progressPercentage As Integer
    41. Public Sub New(bPerSec As Double, ByVal totRec As Long, ByVal totToRec As Long, proPer As Integer)
    42. Me.bytesPerSecond = bPerSec
    43. Me.totalReceived = totRec
    44. Me.totalToReceive = totToRec
    45. Me.progressPercentage = proPer
    46. End Sub
    47. End Class


    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    3. Dim fD As New FileDownload(New Uri("http://download.thinkbroadband.com/100MB.zip"), New IO.DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.Desktop)))
    4. AddHandler fD.DownloadProgressChanged, AddressOf fD_ProgressChanged
    5. AddHandler fD.DownloadCompleted, AddressOf fD_DownloadCompleted
    6. fD.DownloadFile()
    7. End Sub
    8. Private Sub fD_ProgressChanged(ByVal sender As Object, ByVal e As FileDownloadProgressEventArgs)
    9. Dim mbPerSec As String = (e.bytesPerSecond / 1024 / 1024).ToString("N2") & " MB/s"
    10. Label1.BeginInvoke(Sub()
    11. Label1.Text = mbPerSec & vbNewLine & _
    12. e.totalReceived.ToString() & "/" & e.totalToReceive.ToString() & vbNewLine & _
    13. e.progressPercentage.ToString() & "%"
    14. End Sub)
    15. End Sub
    16. Private Sub fD_DownloadCompleted(ByVal sender As Object, ByVal e As EventArgs)
    17. MessageBox.Show("Download complete")
    18. End Sub
    19. End Class


    Ist ein Beispielcode, keine Lösung. Es fehlt komplett die Fehlerbehandlung. Nur schnell getippt....
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    So gehts:

    1.) Deklariert du :

    VB.NET-Quellcode

    1. Dim BytesReceived As Long, Speed As Long, Second As Integer
    2. WithEvents GetSpeed As New System.Windows.Forms.Timer With {.Interval = 1000}


    2.)fügst du diesen Sub hinzu:

    VB.NET-Quellcode

    1. Private Sub GetSpeed_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles GetSpeed.Tick
    2. Second = Second + 1
    3. Dim Length = Convert.ToInt32(BytesReceived / 1000)
    4. Speed = Convert.ToInt32(Length / Second)
    5. End Sub



    3.) nachdem du den Downlaodbefehl gibt schreibst du :

    VB.NET-Quellcode

    1. ' wc.DownloadFileAsync(...)
    2. GetSpeed.Start()


    4.) fügst noch diese FUnction hinzu :

    VB.NET-Quellcode

    1. Function FormatKB(ByVal kb As Long) As String
    2. If kb > 1023 Then
    3. Return Format(kb / 1024, "###,###,##0.00") & " MB\s"
    4. End If
    5. Return kb & " KB\s"
    6. End Function


    5.) und anschließend im DownloadProgresschanged Event von deinen Webclient:

    VB.NET-Quellcode

    1. BytesReceived = e.BytesReceived
    2. lblstatus.Text = "Geschwindigkeit :" & FormatKB(Speed)
    Es ist nichts schlimm an EINEM Timer. Aber...

    Es sollte ein System.Timers.Timer sein, kein Windows.Forms.Timer. Der System.Timers.Timer läuft in einem extra Thread. Würde der TE auf die Idee kommen, mehr als 1 Download zu starten, dann würde er vielleicht auf die Idee kommen, mehrere Timer zu verwenden und hier kann es dann kritisch werden. Je mehr Timer ticken, desto schlechter wird die Performance. Ausserdem "tickt" der WebClient schon oft genug und das kann man sich zu nutze machen.

    Nichts gegen Timer, solange es EINER für das gesamte Projekt ist. Mehrere Timer sind oft ein Zeichen für schlechten Stil, was nicht heissen soll, das meine Codes das Gelbe vom Ei sind.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o