好的,所以我一直在尝试使用不同的方法下载大文件。在我的代码中,通常效果最好的是My.Computer.NetWork.DownloadFile
,但因为文件是1.5Gb,我的窗体冻结并且没有响应。在我等了5分钟之后,我没有等到看多久不会回应,因为我认为这只是浪费时间。所以我也试过wc.DownloadFileAsync
(wc代表Web客户端)这个工作并没有冻结我的窗体,但问题是它跳过它并且不等到下载完成所以它继续用我的代码,因此我得到错误。
我尝试研究暂停或停止代码的方法,直到下载完成但没有运气。经过进一步的研究,我找到了背景工作者课程。我想知道这对我是否有用,我将如何在我的代码中实现它,或者如果有更简单的方法可以做到这一点?
我无法在我的代码中成功实现它。我无法调用,因此出现了这样的错误:Cross-thread operation not valid
。
这是我的代码,后台工作人员:
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim downloader As New System.Net.WebClient
Dim ServerVersion = wc.DownloadString("http://127.0.0.1:8080/patch/PatchList.txt").Trim
Dim tLines As String() = ServerVersion.Split(Environment.NewLine)
For Each NewLine As String In tLines
Dim tVersionAndUrl As String() = NewLine.Split(vbTab)
Dim encText As New System.Text.UTF8Encoding()
Dim btText() As Byte
btText = encText.GetBytes(tVersionAndUrl(0))
'MessageBox.Show(btText.ToString)
'MessageBox.Show(tVersionAndUrl(0)(0))
If tVersionAndUrl.Length < 2 Then
Exit For
End If
If Integer.Parse(tVersionAndUrl(0)) < Integer.Parse(CVersion.Text) Then
Dim TempPath As String = "\launcher\temp.rar"
AddHandler wc.DownloadProgressChanged, AddressOf ProgressChanged
AddHandler wc.DownloadProgressChanged, AddressOf ProgressChanged
AddHandler wc.DownloadFileCompleted, AddressOf DownloadCompleted
'wc.DownloadFileAsync(New Uri(tVersionAndUrl(1)), Me.GetFileName(tVersionAndUrl(1)))
wc.DownloadFileAsync(New Uri(tVersionAndUrl(1)), tmp, Stopwatch.StartNew)
'My.Computer.FileSystem.DeleteFile(Me.GetFileName(tVersionAndUrl(1)))
CVersion.Text = tVersionAndUrl(0)
LabelStatus.Text = "Download in Progress"
Button1.Enabled = False
End If
Next
MsgBox("Client is up to date")
End Sub
这是它的Addhandlers:
Private Sub ProgressChanged(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs)
Dim bytesIn As Double = Double.Parse(e.BytesReceived.ToString())
Dim totalBytes As Double = Double.Parse(e.TotalBytesToReceive.ToString())
Dim percentage As Double = bytesIn / totalBytes * 100
ProgressBarCurrent.Value = Int32.Parse(Math.Truncate(percentage).ToString())
Dim BytesDownloaded As String = (e.BytesReceived / (DirectCast(e.UserState, Stopwatch).ElapsedMilliseconds / 1000.0#)).ToString("#")
If BytesDownloaded < 1024 Then
Dim Bs As String = Convert.ToInt32(BytesDownloaded)
Label4.Text = (Bs & " B/s")
ElseIf BytesDownloaded < 1048576 Then
Dim KBs As String = Math.Round(BytesDownloaded / 1024, 2)
Label4.Text = (KBs & " KB/s")
ElseIf BytesDownloaded < 1073741824 Then
Dim MBs As String = Math.Round(BytesDownloaded / 1048576, 2)
Label4.Text = (MBs & " MB/s")
End If
End Sub
Private Sub DownloadCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs)
'MessageBox.Show("Download Complete")
LabelStatus.Text = "Download Complete"
Button1.Enabled = True
Downloading = False
End Sub
我将不胜感激任何帮助。感谢。
答案 0 :(得分:0)
在较新的VB / C#.net中,您感兴趣的关键字是Await和Async: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1
此外,您应该设计您的例程以块的形式下载。有很多方法可以做到这一点,但也许你最好看看HTTPWebRequest / Response将处理分块,并有一种方法可以轻松地处理+ 2GB文件(范围)。
很抱歉没有答案,因为我没有足够的代表将此作为评论。
干杯, 人
答案 1 :(得分:0)
在你的代码中,我们可以看到你使用了BackgroundWorker类,这对我来说似乎很好。我想要找到的是BackgroundWorker类的剩余委托函数,如 ProgressChanged , RunWorkerCompleted (相反,您已经注册了自己的委托,这可能会导致错误后期)。尝试处理这些事件,它应该可以帮助您,并在任务完成时让您知道并同时报告进度。对于报告进度,在主UI线程中,您还可以运行将style
属性设置为Marquee
的进度条。