【问题标题】:Adding a progressbar that reports the download (source included)添加报告下载的进度条(包括源)
【发布时间】:2021-06-30 09:18:53
【问题描述】:

编程新手,在这里我卡住了我要放置代码以使进度条报告文件下载和写入进度的位置。

源将下载 6 个部分的 100mb 文件,我想要 2 个进度条,1 个标签来报告进度:

  1. 下载进度
  2. 写入文件(如果可能,或者已经是多余的?)
  3. 带有下载进度的标签_MB / MaxFileSize_Mb。
  4. 如何才能更快地下载文件?添加分区是否会使其更快(我对此表示怀疑)?

代码如下。

Imports System.IO
Imports System.Net
Imports System.Threading

Public Class Form1
    Dim efsize, fsize

    Public Class FileDownloader
        Public Start As Integer
        Public Count As Integer
        Public PathTemp As String
        Public Url As String

        Public Sub New(ByVal url As String, ByVal start As Integer, ByVal count As Integer)
            Me.Url = url
            Me.Start = start
            Me.Count = count
        End Sub
    End Class

    Public Shared Function FormatFileSize(ByVal Size As Long) As String
        Try
            Dim KB As Integer = 1024
            Dim MB As Integer = KB * KB
            ' Return size of file in kilobytes.
            If Size < KB Then
                Return (Size.ToString("D") & " bytes")
            Else
                Select Case Size / KB
                    Case Is < 1000
                        Return (Size / KB).ToString("N") & " KB"
                    Case Is < 1000000
                        Return (Size / MB).ToString("N") & " MB"
                    Case Is < 10000000
                        Return (Size / MB / KB).ToString("N") & " GB"
                End Select
            End If
        Catch ex As Exception
            Return Size.ToString
        End Try
    End Function
    Private Sub startDownload()
        ServicePointManager.Expect100Continue = True
        System.Net.ServicePointManager.DefaultConnectionLimit = 1000

        Dim url As String = "https://speed.hetzner.de/100MB.bin"
        Dim filewonloadersList As List(Of FileDownloader) = New List(Of FileDownloader)()
        Dim req As Net.WebRequest = Net.WebRequest.Create(url)
        Dim response = req.GetResponse()
        req.Method = "HEAD"
        Dim resp As Net.WebResponse = req.GetResponse()
        Dim responseLength As Integer = Integer.Parse(resp.Headers.Get("Content-Length"))
        Dim parts As Integer = 6
        Dim eachSize = responseLength / parts
        Dim lastPartSize = eachSize + responseLength Mod parts

        For i As Integer = 0 To parts - 1 - 1
            filewonloadersList.Add(New FileDownloader(url, i * eachSize, eachSize))

        Next

        filewonloadersList.Add(New FileDownloader(url, (parts - 1) * eachSize, lastPartSize))
        Dim threads = New List(Of Thread)()

        For Each item In filewonloadersList
            Task.WhenAll(DoDownload(item))

        Next
    End Sub

    Public Async Function DoDownload(ByVal data As Object) As Task
retry:

        Try
            ServicePointManager.Expect100Continue = True
            System.Net.ServicePointManager.DefaultConnectionLimit = 1000

            Dim downloader = TryCast(data, FileDownloader)
            Dim req As HttpWebRequest = CType(WebRequest.Create(downloader.Url), HttpWebRequest)
            req.AddRange(downloader.Start, downloader.Start + downloader.Count - 1) 'downloader.Start + downloader.Count - 1
            Dim response = Await req.GetResponseAsync()

            Using reponseStream = response.GetResponseStream()


                Using fs = New FileStream($"temp_{downloader.Start}.sth", FileMode.OpenOrCreate)
                    Dim buffer = New Byte(1023) {}
                    Dim bytesRead As Integer = 0

                    Do
                        bytesRead = Await reponseStream.ReadAsync(buffer, 0, 1024)

                        progMain.Value = fs.Length
                        Await fs.WriteAsync(buffer, 0, bytesRead)
                        Await fs.FlushAsync()

                    Loop While bytesRead > 0

                    fs.Close()

                    efsize = FormatFileSize(Convert.ToInt64(bytesRead))

                End Using
            End Using
        Catch e As Exception
            GoTo retry
        End Try
    End Function


    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        startDownload()
    End Sub


End Class

我把它贴在这里作为最后的手段,因为我不知道下一步该做什么。

还请指出正确的方向,让我在探索编程的同时了解更多信息。

我选择了 VB.net,因为我可以轻松地跟踪它并且对新手非常友好。

谢谢!

【问题讨论】:

  • 你在哪里计算进度?如果您不这样做,则没有可报告的进展。如果你这样做,那就是你报告的地方。这里的实际问题是什么:计算进度还是将其报告给 UI?你需要说清楚。

标签: .net vb.net winforms


【解决方案1】:

如果您的表单中有一个 ProgressBar(比如说 ProgressBar1),您可以在每次代码中有“进度”时简单地更新它的值。

例如,通常当你有循环时,你可以报告它:

ProgressBar1.MaxValue = 12
For i as Integer = 0 to 12
    '... some code
    ProgressBar1.Value = i
    Application.DoEvents()   'will update the UI
Next

然后 ProgressBar 可以显示完成的数量百分比。

一般来说,最好是用正确的MultiThread原则来做, 但正如您所提到的,您仍然有点新,并且正在学习自己的方式。

不相关的建议:最好永远不要使用 GoTo(完全)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多