我试图获取托管在FTP
服务器上的文件的大小,并将其放在Label
中,而`BackgroundWorker在后台工作。
我使用“Try”来获取值,但是在第一次尝试时就捕获了该值。下载后,如果我按下尝试再次获得它,那么它的工作。
注意:第一次尝试时,进度条也不工作。
图片
我尝试过的:
Private Sub BWorkerD_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BWorkerD.DoWork
Dim buffer(1023) As Byte
Dim bytesIn As Integer
Dim totalBytesIn As Integer
Dim output As IO.Stream
Dim flLength As Integer
''TRY TO GET FILE SIZE''
Try
Dim FTPRequest As FtpWebRequest = DirectCast(WebRequest.Create(txtFilePathD.Text), FtpWebRequest)
FTPRequest.Credentials = New NetworkCredential(txtFTPUsernameD.Text, txtFTPPasswordD.Text)
FTPRequest.Method = Net.WebRequestMethods.Ftp.GetFileSize
flLength = CInt(FTPRequest.GetResponse.ContentLength)
lblFileSizeD.Text = flLength & " bytes"
Catch ex As Exception
End Try
Try
Dim FTPRequest As FtpWebRequest = DirectCast(WebRequest.Create(txtFilePathD.Text), FtpWebRequest)
FTPRequest.Credentials = New NetworkCredential(txtFTPUsernameD.Text, txtFTPPasswordD.Text)
FTPRequest.Method = WebRequestMethods.Ftp.DownloadFile
Dim stream As IO.Stream = FTPRequest.GetResponse.GetResponseStream
Dim OutputFilePath As String = txtSavePathD.Text & "\" & IO.Path.GetFileName(txtFilePathD.Text)
output = IO.File.Create(OutputFilePath)
bytesIn = 1
Do Until bytesIn < 1
bytesIn = stream.Read(buffer, 0, 1024)
If bytesIn > 0 Then
output.Write(buffer, 0, bytesIn)
totalBytesIn += bytesIn
lblDownloadedBytesD.Text = totalBytesIn.ToString & " bytes"
If flLength > 0 Then
Dim perc As Integer = (totalBytesIn / flLength) * 100
BWorkerD.ReportProgress(perc)
End If
End If
Loop
output.Close()
stream.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
''UPDATE EVERY PROGRESS - DONT WORK ON FIRST TRY''
Private Sub BWorkerD_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BWorkerD.ProgressChanged
pBarD.Value = e.ProgressPercentage
lblPercentD.Text = e.ProgressPercentage & " %"
End Sub
1条答案
按热度按时间3htmauhk1#
主要问题(设置
Option Strict On
以查找更多):您不能从UI Thread以外的线程访问UI对象。
您收到的错误是:
跨线程操作无效:
控件
lblFileSizeD
从创建该控件的线程以外的线程访问然后,
lblDownloadedBytesD
也会出现同样的错误。此外,你正在使用一个空的处理程序来吃掉你的错误消息:
这使任何 * 处理 * 无效,因为没有任何处理。你只是让代码在不采取任何行动的情况下运行它。处理程序是用来处理错误的,而不是让它们不受检查。
当您需要访问和更新某些UI组件属性时,请使用
BackGroundWorker
ReportProgress()方法。此方法有一个接受Object
类型参数的重载。意思是,你可以喂它任何东西。此Object将是ReportProgress
ProgressChangedEventArgs类中的e.UserState属性。.RunWorkerAsync()方法也接受Object参数。此Object将成为BackgroundWorker.DoWork事件的e.Argument属性。这为您实际传递给
BackGroundWorker
的参数提供了一定的灵活性。还有一个问题FTP下载过程不支持取消。当运行时,用户无法停止它。
最后一个问题:正如文档中所报告的那样,您永远不应该在其
DoWork
事件中引用您在UI线程(Form)中示例化的BackGroundWorker
对象。使用sender
对象并将其转换为BackGroundWorker
类。在此示例中,所有UI引用都委托给通过
RunWorkerAsync(Object)
方法(使用e.Argument
属性)传递给DoWork
事件的Class对象。Class对象使用进度详细信息进行更新,然后提供给
ReportProgress(Int32, Object)
方法,该方法在原始同步上下文(UI线程,在其中调用RunWorkerAsync
方法)中运行。可以安全地更新UI。不能发生跨线程操作。
还实现了一种消除方法。这允许中止下载过程并删除部分下载的文件(如果已创建)。
错误处理是最小的,但这是您需要与自己的工具集成的东西。
(我已经为UI控件使用了相同的名称,它应该更容易测试。
操作的视觉结果描述:
A PasteBin of the Form's Designer + Code