我有一个名为SFTPConnectorManager.vb的类,它负责管理与服务器的FTP连接。我有Form1.vb类,它是主要的GUI。我想更新驻留在Form1上的ProgressBar以显示文件传输的进度。负责启动与FTP服务器连接的功能是在新线程上启动的,这样就不会冻结form1,这很好,但是对我来说挑战是能够更新进度条,这对于我一点都没有。
我尝试过/做过的事情:
我需要做什么:
我正在使用的代码:
Form1.vb的
Public Sub sub1(ByVal x As Integer, y As Integer)
StatusLabel2.Text = "Connected"
ProgressBar1.Maximum = ProgressBar1.Maximum + x
ProgressBar1.Value = ProgressBar1.Value + y
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles StartBtn.Click
' If (BackgroundWorker1.IsBusy) <> True Then
' BackgroundWorker1.RunWorkerAsync()
' End If
'Call Xml reader To Get respective values And store them into Class Property
Dim oConnect = New SFTPConnectorManager
Dim oXmlRead As XmlReader = XmlReader.Create("D:\dale_documents\projects\programming\vbnet\remote_data_backup\sftp_backup\settings.xml")
While (oXmlRead.Read())
Dim eType = oXmlRead.NodeType
If (eType = XmlNodeType.Element) Then
If (oXmlRead.Name = "HostName") Then
oConnect.HostName = oXmlRead.ReadInnerXml.ToString
End If
If (oXmlRead.Name = "UserName") Then
oConnect.UserName = oXmlRead.ReadInnerXml.ToString
End If
If (oXmlRead.Name = "Password") Then
oConnect.Password = oXmlRead.ReadInnerXml.ToString
End If
If (oXmlRead.Name = "Port") Then
oConnect.Port = oXmlRead.ReadInnerXml.ToString
End If
If (oXmlRead.Name = "Protocol") Then
oConnect.ProtocolSelection = oXmlRead.ReadInnerXml.ToString
End If
If (oXmlRead.Name = "FTPMode") Then
oConnect.FtpModeSelection = oXmlRead.ReadInnerXml.ToString
End If
If (oXmlRead.Name = "SSHFingerPrint") Then
oConnect.SSHKey = oXmlRead.ReadInnerXml.ToString
End If
If (oXmlRead.Name = "Remotepath") Then
oConnect.RemotePath = oXmlRead.ReadInnerXml.ToString
End If
If (oXmlRead.Name = "Localpath") Then
oConnect.LocalPath = oXmlRead.ReadInnerXml.ToString
End If
End If
End While
Dim eProtocolOptions = oConnect.ProtocolSelection
Dim sUserName = oConnect.UserName
Dim sHostName = oConnect.HostName
Dim sPassword = oConnect.Password
Dim sSSHKey = oConnect.SSHKey
Dim iPort = oConnect.Port
Dim sRemotePath = oConnect.RemotePath
Dim sLocalPath = oConnect.LocalPath
Dim bFlag = oConnect.bFlag
Dim asOptions = New String() {eProtocolOptions, sHostName, sUserName, iPort, sPassword, sSSHKey, sRemotePath, sLocalPath}
oConnect.TestThread(asOptions)
SFTPConnectorManager.vb
Function StartConnectionThread(asOptions)
Try
Dim oSessionOptions As New SessionOptions
With oSessionOptions
.Protocol = ProtocolSelection
.HostName = HostName
.UserName = UserName
.PortNumber = Port
.Password = Password
.SshHostKeyFingerprint = SSHKey
End With
Using oSession As New Session
AddHandler oSession.FileTransferProgress, AddressOf SessionFileTransferProgress
oSession.Open(oSessionOptions)
Dim oTransferOptions As New TransferOptions
oTransferOptions.TransferMode = TransferMode.Binary
oSession.GetFiles(RemotePath, LocalPath, False, oTransferOptions)
oSession.Close()
bFlag = False
End Using
MessageBox.Show("File Transfer Compelete")
Return 0
Catch ex As Exception
MessageBox.Show(ex.ToString())
Return 1
End Try
End Function
Public Delegate Sub SetbarValues(maximum As Integer, value As Integer)
Private Sub SessionFileTransferProgress(ByVal sender As Object, ByVal e As FileTransferProgressEventArgs)
Dim oForm1 = Form1
Dim msd As SetbarValues = AddressOf oForm1.sub1
If oForm1.InvokeRequired Then
msd.Invoke(1, 1)
Else
oForm1.sub1(1, 1)
End If
'oForm1.ProgressUpdate()
'If (Form1.CheckForIllegalCrossThreadCalls) Then
' MsgBox("Illegal cross-thread operation deteced.")
'End If
End Sub
Public Sub TestThread(asOption())
Dim oSFTPConnectionManager = New SFTPConnectorManager
Dim Thread As New Thread(AddressOf oSFTPConnectionManager.StartConnectionThread)
oSFTPConnectionManager.ProtocolSelection = asOption(0)
oSFTPConnectionManager.HostName = asOption(1)
oSFTPConnectionManager.UserName = asOption(2)
oSFTPConnectionManager.Port = asOption(3)
oSFTPConnectionManager.Password = asOption(4)
oSFTPConnectionManager.SSHKey = asOption(5)
oSFTPConnectionManager.RemotePath = asOption(6)
oSFTPConnectionManager.LocalPath = asOption(7)
Thread.Start()
End Sub
所以你可能会看到我试图使用一个委托,我做了一些相关的阅读,我相信这是我需要从一个单独的线程更新UI元素,但我显然误解了它,因为我可以在我自己的项目中实现这个概念。 UI会在SessionFileTransferProgress事件期间更改NEEDS。
请男孩们和女孩们以我的智慧结束这一点,这是我最后的拯救恩典,如果我无法理解并实施这些概念,我认为我不会继续学习编程。< / p>
答案 0 :(得分:1)
这是一个显示概念的简单示例。它有一个类,它有一些长时间运行(sic)活动,想要向UI报告进度。您需要一个包含两个按钮,一个进度条和一个文本框的表单。希望这在概念上有所帮助。
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ProgressBar1.Value = 0
Dim foo As New SomeClass(New Action(AddressOf showProg))
foo.SimulateActivity() 'long running
Button2.Select()
End Sub
Public Sub showProg()
If Me.InvokeRequired Then ' on the UI?
Me.Invoke(Sub() showProg()) ' no, run this on the UI
Else
ProgressBar1.Increment(1) ' yes, on the UI
End If
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
'test if UI available while long running
'press button 2 while long running to confirm UI
TextBox1.Text = ProgressBar1.Value.ToString
End Sub
End Class
Public Class SomeClass
Private _action As Action
Public Sub New(progress As Action)
Me._action = progress
End Sub
Public Sub SimulateActivity()
'runs on thread
Dim t As Task
t = Task.Run(Sub()
For x As Integer = 1 To 100
Me._action()
Threading.Thread.Sleep(50)
Next
End Sub)
End Sub
End Class