下载带开始/暂停/停止的文件 [英] Download File With Start / Pause / Stop

查看:70
本文介绍了下载带开始/暂停/停止的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有什么方法可以在我的vb程序中暂停文件下载?我已经尝试了http方法和my.computer.net方法,没有运气。我也试过通过这种方法暂停后台工作者:[URL]但是即使暂停了bgworker,下载也会继续.....



Is there any way i can pause a file download in my vb program?? I have tried both the http method and the my.computer.net method with no luck. I have also tried pausing the background worker by this method: [URL] But even if the bgworker is paused the download goes on.....

Dim locationfiledownload As String
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)
    ToolStripButton2.Enabled = True
    ToolStripButton3.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.RadProgressBar1.Value1 = 0
    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.Label4.Text = "Downloaded " & Math.Round((position / 1024), 2) & " KB of " & Math.Round((length / 1024), 2) & "KB"
    Me.RadProgressBar1.Value1 = percent
End Sub

Public Sub btnDownload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripButton2.Click
    locationfiledownload = GetPage("http://asankonkur.ir/update/locationfiledownload.txt")

    If locationfiledownload <> "" AndAlso locationfiledownload.StartsWith("http://") Then

        Me.SaveFileDialog1.FileName = locationfiledownload.Split("/"c)(locationfiledownload.Split("/"c).Length - 1)
        If Me.SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
            Me.whereToSave = Me.SaveFileDialog1.FileName
            Me.SaveFileDialog1.FileName = ""

            ToolStripButton2.Enabled = False
            ToolStripButton3.Enabled = True

            Me.BackgroundWorker2.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 BackgroundWorker2_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker2.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(locationfiledownload)
        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 BackgroundWorker2.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.BackgroundWorker2.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 ToolStripButton3.Click
    Me.BackgroundWorker2.CancelAsync() 'Send cancel request
End Sub

推荐答案

对于暂停/恢复线程,请使用类系统.Threading.EventWaitHandle System.Thre ading.ManualResetEvent (如果您使用手动重置,这些类的行为完全相同)。在一个线程中,您使用 System.Threading.EventWaitHandle.WaitOne 。这是一个阻止代码。如果事件被重置(处于无信号状态状态),它将切换出你的下载线程并使其处于等待状态,也就是说,线程不会被安排回执行直到唤醒。因此,等待花费零CPU时间。某些线程将被 Thread.Abort 唤醒,或者当发出相同的实例 EventWaitHandle 时,您可以在某些情况下执行此操作不同的(比方说,UI)线程,通过调用 EventWaitHandle.Set 。这是你暂停/恢复你的线程的机制。



过时的方法暂停/恢复是不安全的,应该是使用。



至于下载,我宁愿建议使用 System.Net.HttpWebRequest 。请参阅:

http://msdn.microsoft.com /en-us/library/system.net.webrequest.aspx [ ^ ],

http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.aspx [ ^ ]。



与另一种方法,这个类允许你一个接一个地顺序下载一个文件,这样你就可以在块之间插入 EventWaitHand.WaitOne 。基于事件的更高级别(更少直接)方法不允许您这样做。有关完整的代码示例,请参阅我的应用程序HttpDownloader:

如何从互联网上下载文件 [ ^ ]。



另请参阅我过去对该主题的其他答案:

如何获取数据来自其他网站 [ ^ ],

从网页获取特定数据 [ ^ ]。< br $>


-SA
For pausing/resuming thread, use the class System.Threading.EventWaitHandle or System.Threading.ManualResetEvent (the behavior of these classes are exactly identical in case you use manual reset). In a thread, you use System.Threading.EventWaitHandle.WaitOne. This is a blocking code. If the event is reset (is in nonsignaled state), it will switch out your downloading thread and put it in the wait state, that is, the thread won''t be scheduled back to execution until awaken. So, the wait spends zero CPU time. The thread will be awaken by Thread.Abort or when the same instance EventWaitHandle is signaled, which you can do in some different (say, UI) thread, by calling EventWaitHandle.Set. This is your mechanism for suspending/resuming your thread.

Obsolete methods Suspend/Resume are unsafe and should be be used.

As to downloading, I would rather advise to use System.Net.HttpWebRequest. Please see:
http://msdn.microsoft.com/en-us/library/system.net.webrequest.aspx[^],
http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.aspx[^].

In contrast to other method, this class will allow you to download a file sequentially, piece by piece, so you can insert EventWaitHand.WaitOne between blocks. More high-level (less direct) methods based on events won''t allow you to do so. For a complete code sample, please see my application HttpDownloader:
how to download a file from internet[^].

Please see also my other past answers on the topic:
How to get the data from another site[^],
get specific data from web page[^].

—SA


这篇关于下载带开始/暂停/停止的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆