【问题标题】:Download file using backgroundworker [duplicate]使用后台工作者下载文件
【发布时间】:2014-09-06 13:38:31
【问题描述】:

我想使用 backgroundworker 下载两个 zip 文件,但是当我想下载文件时,它给我的错误是 backgoundworker 很忙,无法同时运行多个任务。这是代码

Imports System.Net
Public Class mainForm

Dim whereToSave As String 'Where the program save the file
Private files() As String = {}
Private dlCount As Integer = 0
Delegate Sub ChangeTextsSafe(ByVal length As Long, ByVal position As Integer, ByVal percent As Integer, ByVal speed As Double)
Delegate Sub DownloadCompleteSafe(ByVal cancelled As Boolean)

Public Sub DownloadComplete(ByVal cancelled As Boolean)
    'Me.txtFileName.Enabled = True
    Me.btnDownload.Enabled = True
    Me.btnCancel.Enabled = False

    If cancelled Then

        Me.Label4.Text = "Cancelled"

        MessageBox.Show("Download aborted", "Aborted", MessageBoxButtons.OK, MessageBoxIcon.Information)


    Else
        Me.Label4.Text = "Successfully downloaded"

        MessageBox.Show("Successfully downloaded!", "All OK", MessageBoxButtons.OK, MessageBoxIcon.Information)


    End If

    Me.ProgressBar1.Value = 0
    'Me.Label5.Text = "Downloading: "
    'Me.Label6.Text = "Save to: "
    'Me.Label3.Text = "File size: "
    'Me.Label2.Text = "Download speed: "
    Me.Label4.Text = ""

End Sub

点击下载按钮

   Private Sub btnDownload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDownload.Click
    Me.btnDownload.Enabled = False
    Me.btnCancel.Enabled = True
    Dim TestString As String = "http://ec2-54-76-30-19.eu-west-1.compute.amazonaws.com/manapps/IDGo800_Minidriver_32.zip," & _
       "http://ec2-54-76-30-19.eu-west-1.compute.amazonaws.com/manapps/IDGo800_Minidriver_64.zip"
    Dim strFile As String
    Dim length As Long
    Dim position As Integer
    Dim percent As Integer
    Dim speed As Double
    files = TestString.Split(CChar(","))
    Dim a As String

    For Each a In files
        Dim b() As String = a.Split("/"c)
        strFile = b(b.Length - 1)
        'Dim strFileName As String = ""
        'MsgBox(a)
        'MsgBox(strFile)

        Me.whereToSave = "C:\Temp\" & strFile
        Me.DownloadingLabel.Text = "Downloading: " & strFile
        Me.SaveToLabel.Text = "Save To: " & strFile
        Me.FileSizeLabel.Text = "File Size: " & Math.Round((length / 1024), 2) & " KB"
        Me.Label4.Text = "Downloaded " & Math.Round((position / 1024), 2) & " KB of " & Math.Round((length / 1024), 2) & "KB (" & Me.ProgressBar1.Value & "%)"
        If speed = -1 Then
            Me.DownloadSpeedLabel.Text = "Speed: calculating..."
        Else
            Me.DownloadSpeedLabel.Text = "Speed: " & Math.Round((speed / 1024), 2) & " KB/s"
        End If
        Me.ProgressBar1.Value = percent
        dlCount = 0
        StartDownload()
    Next

End Sub

调用下载函数

Private Sub StartDownload()
    dlCount += 1
    If dlCount <= files.Length Then
        BackgroundWorker1.RunWorkerAsync(files(dlCount - 1))
    Else
        MessageBox.Show("All files Downloaded")
        'Button1.Enabled = True
    End If
End Sub

后台工作人员

Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    Dim arg As String = DirectCast(e.Argument, String)
    'Creating the request and getting the response
    Dim theResponse As HttpWebResponse
    Dim theRequest As HttpWebRequest
    Try 'Checks if the file exist

        theRequest = WebRequest.Create(arg)
        theResponse = theRequest.GetResponse
    Catch ex As Exception

        MessageBox.Show("An error occurred while downloading file. Possibe causes:" & ControlChars.CrLf & _
                        "1) File doesn't exist" & ControlChars.CrLf & _
                        "2) Remote server error", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Exit Sub
    End Try
End Sub

如果完成,它将调用 backgroundcomplete

Private Sub bgw_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    StartDownload()
End Sub

【问题讨论】:

    标签: vb.net backgroundworker downloadfile


    【解决方案1】:

    进口 System.Net 公共类mainForm

    Dim whereToSave As String 'Where the program save the file
    
    Delegate Sub ChangeTextsSafe(ByVal length As Long, ByVal position As Integer, ByVal percent As Integer, ByVal speed As Double)
    Delegate Sub DownloadCompleteSafe(ByVal cancelled As Boolean)
    
    Public Sub DownloadComplete(ByVal cancelled As Boolean)
        Me.txtFileName.Enabled = True
        Me.btnDownload.Enabled = True
        Me.btnCancel.Enabled = False
    
        If cancelled Then
    
            Me.Label4.Text = "Cancelled"
    
            MessageBox.Show("Download aborted", "Aborted", MessageBoxButtons.OK, MessageBoxIcon.Information)
    
    
        Else
            Me.Label4.Text = "Successfully downloaded"
    
            MessageBox.Show("Successfully downloaded!", "All OK", MessageBoxButtons.OK, MessageBoxIcon.Information)
    
    
        End If
    
        Me.ProgressBar1.Value = 0
        Me.Label5.Text = "Downloading: "
        Me.Label6.Text = "Save to: "
        Me.Label3.Text = "File size: "
        Me.Label2.Text = "Download speed: "
        Me.Label4.Text = ""
    
    End Sub
    
    Public Sub ChangeTexts(ByVal length As Long, ByVal position As Integer, ByVal percent As Integer, ByVal speed As Double)
    
        Me.Label3.Text = "File Size: " & Math.Round((length / 1024), 2) & " KB"
    
        Me.Label5.Text = "Downloading: " & Me.txtFileName.Text
    
        Me.Label4.Text = "Downloaded " & Math.Round((position / 1024), 2) & " KB of " & Math.Round((length / 1024), 2) & "KB (" & Me.ProgressBar1.Value & "%)"
    
        If speed = -1 Then
            Me.Label2.Text = "Speed: calculating..."
        Else
            Me.Label2.Text = "Speed: " & Math.Round((speed / 1024), 2) & " KB/s"
        End If
    
        Me.ProgressBar1.Value = percent
    
    
    End Sub
    
    Private Sub btnDownload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDownload.Click
    
        If Me.txtFileName.Text <> "" AndAlso Me.txtFileName.Text.StartsWith("http://") Then
    
    
            Me.SaveFileDialog1.FileName = TextBox1.Text
    
            If Me.SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
    
                Me.whereToSave = Me.SaveFileDialog1.FileName
    
                Me.SaveFileDialog1.FileName = ""
    
                Me.Label6.Text = "Save to: " & Me.whereToSave
    
                Me.txtFileName.Enabled = False
                Me.btnDownload.Enabled = False
                Me.btnCancel.Enabled = True
    
                Me.BackgroundWorker1.RunWorkerAsync() 'Start download
    
            End If
    
        Else
    
            MessageBox.Show("Please insert valid URL for download", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning)
    
        End If
    
    End Sub
    
    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    
        'Creating the request and getting the response
        Dim theResponse As HttpWebResponse
        Dim theRequest As HttpWebRequest
        Try 'Checks if the file exist
    
            theRequest = WebRequest.Create(Me.txtFileName.Text)
            theResponse = theRequest.GetResponse
        Catch ex As Exception
    
            MessageBox.Show("An error occurred while downloading file. Possibe causes:" & ControlChars.CrLf & _
                            "1) File doesn't exist" & ControlChars.CrLf & _
                            "2) Remote server error", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
    
            Dim cancelDelegate As New DownloadCompleteSafe(AddressOf DownloadComplete)
    
            Me.Invoke(cancelDelegate, True)
    
            Exit Sub
        End Try
        Dim length As Long = theResponse.ContentLength 'Size of the response (in bytes)
    
        Dim safedelegate As New ChangeTextsSafe(AddressOf ChangeTexts)
        Me.Invoke(safedelegate, length, 0, 0, 0) 'Invoke the TreadsafeDelegate
    
        Dim writeStream As New IO.FileStream(Me.whereToSave, IO.FileMode.Create)
    
        'Replacement for Stream.Position (webResponse stream doesn't support seek)
        Dim nRead As Integer
    
        'To calculate the download speed
        Dim speedtimer As New Stopwatch
        Dim currentspeed As Double = -1
        Dim readings As Integer = 0
    
        Do
    
            If BackgroundWorker1.CancellationPending Then 'If user abort download
                Exit Do
            End If
    
            speedtimer.Start()
    
            Dim readBytes(4095) As Byte
            Dim bytesread As Integer = theResponse.GetResponseStream.Read(readBytes, 0, 4096)
    
            nRead += bytesread
            Dim percent As Short = (nRead * 100) / length
    
            Me.Invoke(safedelegate, length, nRead, percent, currentspeed)
    
            If bytesread = 0 Then Exit Do
    
            writeStream.Write(readBytes, 0, bytesread)
    
            speedtimer.Stop()
    
            readings += 1
            If readings >= 5 Then 'For increase precision, the speed it's calculated only every five cicles
                currentspeed = 20480 / (speedtimer.ElapsedMilliseconds / 1000)
                speedtimer.Reset()
                readings = 0
            End If
        Loop
    
        'Close the streams
        theResponse.GetResponseStream.Close()
        writeStream.Close()
    
        If Me.BackgroundWorker1.CancellationPending Then
    
            IO.File.Delete(Me.whereToSave)
    
            Dim cancelDelegate As New DownloadCompleteSafe(AddressOf DownloadComplete)
    
            Me.Invoke(cancelDelegate, True)
    
            Exit Sub
    
        End If
    
        Dim completeDelegate As New DownloadCompleteSafe(AddressOf DownloadComplete)
    
        Me.Invoke(completeDelegate, False)
    
    End Sub
    
    Private Sub mainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.Label4.Text = ""
    End Sub
    
    Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
        Me.BackgroundWorker1.CancelAsync() 'Send cancel request
    End Sub
    
    
    End Class
    

    【讨论】:

    • 您能详细说明一下吗?
    【解决方案2】:

    vb.net 不太好。但为什么不使用任务。我认为他们更适合这样的行动。

    Sub Main()
    
    
        Task.Factory.StartNew(Function() DownloadFile())
    
    
    End Sub
    
    Private Sub DownloadFile()
        Dim webClient1 As New WebClient()
        webClient1.DownloadFile("htt:\\one.two.three.com\file", "something.txt")
    End Sub
    

    所有文件都可以同时下载。

    【讨论】:

    • 我不使用 webclient,因为我想在使用 httpwebrequest 时添加一些东西,例如恢复下载,这将是范围标头。不知道webclient有没有这种功能
    【解决方案3】:

    您的代码看起来正确 添加此代码并重试If Not Me.BGWorkerTwo.IsBusy Then Me.BGWorkerTwo.RunWorkerAsync()

    【讨论】:

    • 你的意思是这样吗? If Not BackgroundWorker1.IsBusy Then dlCount += 1 If dlCount
    • 抱歉回复晚了。是的,我试过了,它说后台工作人员很忙。
    • 请告诉你为什么在bgw_RunWorkerCompleted中写StartDownload()?bgw_RunWorkerCompleted 从DoWork接收结果,并显示出来。
    • 如果下载完成,它将转到子下载并读取 Else MessageBox.Show("All files Downloaded") 'Button1.Enabled = True End If
    • 做一件事,请从 RunWorkerCompleted 中删除您的代码,并尽可能检查您是否得到相同的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多