as the title suggests I am trying to update a progress bar using an event handler that is spawned by a function in a separate class. I think it's something to do with delegation and ownership of the form however I'm at a loss as to how to implement this properly as all the suggestions are in C# and my attempts at conversion have either errored out or just not worked at all.
My code performs a simple function, using WinSCP it downloads a file (or folder) from a remote directory to a local one, this functionality works fine. However I'm attempting to make progress bars to track the total progress of downloads as some of these may become long operations.
I have set up a BackgroundWorker to fulfil this task and as it stands if I have the function in another class (Desirable due to the nature of how I like to code, to avoid mess etc..) the progress bar does not update on the form, though the values are definitely there as proven by break-points.
Please see below my code, any opinions for help are much appreciated.
This is inside my class BackupUtility.vb (The form class)
Imports System.ComponentModel
Imports WinSCP
Public Class BackupUtility
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If Not BackgroundWorker.IsBusy Then
BackgroundWorker.RunWorkerAsync()
End If
End Sub
Private Sub BackgroundWorker_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker.DoWork
testBackupServer()
End Sub
Public Sub BackgroundWorker_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles BackgroundWorker.ProgressChanged
Dim progress = e.UserState
TotalDownloadFileProgress.Value = progress.FileProgress
TotalDownloadProgress.Value = progress.FolderProgress
Label1.Text = progress.fileprogress
End Sub
Public Function testBackupServer() As Task
Dim progressObject As New DownloadProgress
Dim sessionOptions As New SessionOptions
With sessionOptions
.Protocol = Protocol.Sftp
.HostName = "********"
.UserName = "********"
.Password = "********"
.SshHostKeyPolicy = SshHostKeyPolicy.GiveUpSecurityAndAcceptAny
End With
sessionOptions.AddRawSettings("FSProtocol", "2")
Using session As New Session
AddHandler session.FileTransferProgress,
Sub(sender, e)
progressObject.FileProgress = e.FileProgress * 100
progressObject.FolderProgress = e.OverallProgress * 100
BackgroundWorker.ReportProgress(1, progressObject)
End Sub
' Connect
session.Open(sessionOptions)
' Transfer files
session.GetFiles("remote directory", "output directory").Check()
End Using
End Function
End Class
Please bare in mind that DownloadProgress is a simple class object I made to pass multiple values through the ReturnProgress event.
The above code works in the sense that it performs what I want, it downloads the file AND updates the progress bar, but this is undesirable as my final vision for this project will get very messy very quickly if I have to contain it all inside of one big class.
I want to be able to invoke the progress bar from outside of the class without it giving me the error "Invoke or BeginInvoke cannot be called on a control until the window handle has been created"
If any of you have further questions I'll be more than happy to provide, apologies if this is long winded, I'm not overly experienced with asking questions here, much more of a lurker. Thanks in advance!
EDIT: DownloadProgress is a value storage class for passing between event handlers, it is not the progress bar. The progress bars are "TotalDownloadProgress" and "TotalDownloadFileProgress"