0

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.

Ste Moore
  • 107
  • 1
  • 10
  • 1
    2 year old's don't program and barely speak, are you sure you want that dialog? – OneFineDay Jun 12 '15 at 15:13
  • Well, maybe a little older. Haha – Ste Moore Jun 12 '15 at 15:17
  • http://stackoverflow.com/q/8986810/1070452 just one of the 10 suggested questions listed to the right under "RELATED". I didnt check the "speaking to" level though. A thread seems a bit much, BTW. – Ňɏssa Pøngjǣrdenlarp Jun 12 '15 at 15:17
  • Thanks for pointing that out, but I've already looked at lots of these pages and couldn't figure out how to return the data from another class. I've had it working from the form but I had to change it to be part of another class because it wasn't working correctly. – Ste Moore Jun 12 '15 at 15:28
  • Did you vote me down? That's a bit rude. My question isn't covered in any of the posts I've found. I'm trying to get the result of a function on a different class. All the others are from the same form. – Ste Moore Jun 12 '15 at 15:42

1 Answers1

0

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.

Btc Sources
  • 1,912
  • 2
  • 30
  • 58
  • Thanks for the explanation, but where do I Invoke it? Is it in the button click event, the new event on the class, or the PerformFTP event? – Ste Moore Jun 12 '15 at 15:25
  • Just where you were going to do it, after getting your text for the control, but using the delegate. That happens in your thread if I don't missunderstood it. – Btc Sources Jun 12 '15 at 15:27
  • Sorry, I'm still not getting it. Using my example above, where would I put an invoke? I tried adding it to PerformFTP but it didn't do anything. If I add it to cmdRun_Click how do I get the result of PerformFTP? – Ste Moore Jun 12 '15 at 15:40
  • Update the question putting how you tried to use it @SteMoore – Btc Sources Jun 12 '15 at 17:27