Threading Problems (I don't understand it)

69 views Asked by At

There's lots and lots of pages on the internet regarding threading but I can't seem to get my head around it.

I have a Form, which on the click of a button, loops through a file and reads it line by line. Each line is the login details for different FTP sites.

When it reads a line, it Dim's a variable as a new instance of a class named CallFTP using the login details.

It then Dim's a variable as a new Thread using a function in CallFTP named PerformFTP.

PerformFTP returns a string with the results of the FTP and I want to add this to a ListBox on the form that began it all.

The code for the button goes like this...

Private Sub cmdRun_Click(sender As Object, e As EventArgs) Handles cmdRun.Click
    For Each _FTPLine As String In Split(_FTPDetails, vbNewLine)
        Dim _Active As Boolean = CBool(Split(_FTPLine, "|")(7))

        If _Active Then
            _CurNum += 1
            _ID = Format(Now.Year, "0000") & Format(Now.Month, "00") & Format(Now.Day, "00") & Format(Now.Hour, "00") & Format(Now.Minute, "00") & Format(Now.Second, "00") & Format(Now.Millisecond, "000") & Format(_CurNum, "00000")

            Dim _FTP As New CallFTP(_ID, Split(_FTPLine, "|")(0), Split(_FTPLine, "|")(1), Split(_FTPLine, "|")(2), Split(_FTPLine, "|")(3), Split(_FTPLine, "|")(4), Split(_FTPLine, "|")(5), Split(_FTPLine, "|")(6))
            Dim _Thread = New Thread(New ThreadStart(AddressOf _FTP.PerformFTP))

            With _Thread
                .IsBackground = True
                .Start()
            End With
        End If
    Next _FTPLine
End Sub

The class is as below (not quite but you don't need the rest of the code lol)

Public Class CallFTP
    Private _ID As String = ""
    Private _Response As String = ""
    Private _IPAddress As String = ""
    Private _Port As String = ""
    Private _User As String = ""
    Private _Pass As String = ""
    Private _Remote As String = ""
    Private _Local As String = ""
    Private _InOut As String = ""

    Public Sub New(ID As String, Server As String, PortNum As String, Username As String, Password As String, RemoteDir As String, LocalDir As String, InOrOut As String)
        _ID = ID
        _IPAddress = Server
        _Port = PortNum
        _User = Username
        _Pass = Password
        _Remote = RemoteDir
        _Local = LocalDir
        _InOut = InOrOut
    End Sub

    Public Function PerformFTP() As String
        Return "This is a test"
    End Function
End Class

Could anyone explain how I would call a sub named LogMessage on a module named modMisc (which adds a string to a ListBox on the main form)?

I've read that you need to invoke it but everything I read seems to give me a headache and make me need to lie down in a dark room for a few hours.

Is anyone capable of explaining as though you're speaking to a 2 year old? :)

Any help would be much appreciated.

1

There are 1 answers

4
Btc Sources On

You need to invoke a delegate to update your GUI if you're going to update it from another thread that from where it was created.

1º Your delegate must match (have the same signature) than the method you'll use:

    Delegate Sub LogMessageExampleDelegate(ByVal x As Integer, ...)

Signature means that the delegate must return and receive the same types than your function/method.

2º Call your function to update GUI using delegate. This for example inside your update GUI function:

If yourListBox.InvokeRequired Then
    yourListBox.Invoke(New LogMessageExampleDelegate(AddressOf THE_FUNCTION_WHICH_UPDATES_THE_GUI_NAME), parameter_value)
Else
    'Just call your function
End If

With, as example:

sub addToListBox(byval text as string)
    myListBox.Items.add(text)
end sub

So your invoke would be:

If yourListBox.InvokeRequired Then
    yourListBox.Invoke(New LogMessageExampleDelegate(AddressOf addToListBox), "Item 1")
Else
    'Just call your function
    addToListBox("Item 1")
End If

PS: I wrote it two times so hope I didn't mess up with something without noticing it.