Having Trouble Updating Form from thread outside of Class

ravi_elite

New member
Joined
Dec 15, 2013
Messages
2
Programming Experience
3-5
I know that you guys probably get this question alot..and trust me when i say I have been doing plently of searching..and i am stumped... invokes and threads have really been getting on my nerves ... anyway I am building an special irc client... it all connects that is not the issue.. what is the issue is that ..it only updates the information to the form through the single form file..which is not what i want to do..what i wanted to do was put the Connection code into its own class.. which still connects..but will now not update form1 I know the sub is being reached because i placed a message box to see and it works.. its just not updating the form so anyway here is the code
VB.NET:
Imports System.Net.Sockets
Imports WindowsApplication1.Form1
Public Class Class1
    Public Client As TcpClient
    Public Stream As NetworkStream
    Private ChOK As String
    Private Const MSNChatVersionStr As String = "IRCVERS IRC5"
    Private Const MSNChatAuthenticationInitStr As String = "AUTH GateKeeper I :GKSSP\0r\0\0\0\0\0\0"
    Dim MyFormThread As Threading.Thread
    Public Sub Connect()
        'Me.StatusBox.BackColor = Color.Blue
        'Me.StatusBox.ForeColor = Color.White()
        Form1.PowerOn()
        Try
            Dim server As String
            server = "157.56.180.51"
            Dim port As New Int32
            port = "6667"
            Client = New TcpClient(server, port)
            Dim message As String = MSNChatVersionStr & vbLf & MSNChatAuthenticationInitStr & vbCrLf
            Dim data As [Byte]() = System.Text.Encoding.ASCII.GetBytes(message)
            Stream = Client.GetStream()
            Stream.Write(data, 0, data.Length)
            Dim data2 As [Byte]()
            data2 = New [Byte](513) {}
            Dim responseData As [String] = [String].Empty
            Dim bytes As Int32 = Stream.Read(data2, 0, data2.Length)
            Do While bytes > 0
                Do While Stream.DataAvailable
                    bytes = Stream.Read(data2, 0, data2.Length)
                    responseData = Trim(System.Text.Encoding.ASCII.GetString(data2, 0, bytes))
                    Dim Feed As String() = responseData.Split(Chr(10), Chr(13))
                    'Dim Feed As String() = responseData.Split(New [Char]() {vbCrLf, vbLf})
                    'Dim line As String
                    For Each line As String In Feed
                        If line.Trim() <> "" Then
                            'MsgBox(line)
                            Select Case UCase(Split(line.Trim, " ")(0))
                                Case "AUTH"
                                    If (Split(line, " ")(2) = "S") And (Split(line, " ")(3) <> ":OK") Then
                                        ChOK = ":GKSSP\0\0\0" & Chr(2) & "\0\0\0" & Chr(3) & "\0\0\0" & Pack_binary_data(Challenge_1(Mid(line, InStr(line, "\0\0\0\0\0\0") + Len("\0\0\0\0\0\0"))), False) & "Sm(" & _
                                        HexToAsc("e4") & "HS" & HexToAsc("c1") & "M" & HexToAsc("847f8293f98d") & "UC"
                                        message = "AUTH GateKeeper S " & ChOK & vbCrLf
                                        'StatusBox.AppendText(message)
                                        Dim datax As [Byte]() = System.Text.Encoding.Default.GetBytes(message)
                                        Stream.Write(datax, 0, datax.Length)
                                    ElseIf (Split(line, " ")(2) = "*") Then
                                        message = "USER IRC7 * * :BlueNexus" + vbCrLf + "Nick >ghost" + vbCrLf
                                        Dim datax As [Byte]() = System.Text.Encoding.Default.GetBytes(message)
                                        Stream.Write(datax, 0, datax.Length)
                                    End If
                                Case "PING"
                                    message = "PONG " + Split(line.Trim, " ")(1) + vbCrLf
                                    Dim datax As [Byte]() = System.Text.Encoding.Default.GetBytes(message)
                                    Stream.Write(datax, 0, datax.Length)
                            End Select
                            Select Case UCase(Split(line.Trim, " ")(1))
                                Case "422"
                                    message = "JOIN %#lobby" + vbCrLf
                                    Dim datax As [Byte]() = System.Text.Encoding.Default.GetBytes(message)
                                    Stream.Write(datax, 0, datax.Length)
                                Case "001"

                                Case "JOIN"
                                    Threading.Thread.Sleep(10)
                                    'MessageChannel(line, "JOIN")
                                Case "353"
                                    Dim sChannel = Split(line, " ")(4)
                                    Dim sTemp = Split(line, sChannel & " :")(1)
                                    'MsgBox sTemp
                                    '--- NickList.Items.Clear()
                                    'CreateNickList(sTemp)
                                Case "332"
                                    Threading.Thread.Sleep(10)
                                    'ViewChannel(1)

                                    'SetChannelTopic(line)

                                    message = "MODE %#lobby" + vbCrLf
                                    Dim datax As [Byte]() = System.Text.Encoding.Default.GetBytes(message)
                                    Stream.Write(datax, 0, datax.Length)
                                Case "324"
                                    Threading.Thread.Sleep(10)
                                    ' SetChannelModes(Split(line.Trim, " ")(4) + " " + Split(line.Trim, " ")(5))
                                Case "PRIVMSG"
                                    Threading.Thread.Sleep(10)
                                    'MessageChannel(line, "PRIVMSG")
                                Case "910"
                                    Stream.Close()
                                    Client.Close()
                                    message = "Authentication Failed...Closing Socket & Retrying!!!!" + vbCrLf
                                    'echoStatusBox(message)
                                    Connect()
                                Case "PART"
                                    Threading.Thread.Sleep(10)
                                    'MessageChannel(line, "PART")
                                Case "QUIT"
                                    Threading.Thread.Sleep(10)
                                    'MessageChannel(line, "QUIT")
                                Case "MODE"
                                    Threading.Thread.Sleep(10)
                                    'MessageChannel(line, "MODE")
                                Case Else

                            End Select
                        End If
                    Next
                    Threading.Thread.Sleep(10)
                    'StatusBox.AppendText(responseData)
                    Form1.echoStatusBox(responseData)
                    'MsgBox(responseData)
                Loop
                Threading.Thread.Sleep(1000)
            Loop
            Stream.Close()
            Client.Close()
        Catch e As ArgumentNullException
        Catch e As SocketException
        End Try
    End Sub
End Class
^ Class1


VB.NET:
    Public Sub echoStatusBox(response As String)
        If Me.StatusBox.InvokeRequired Then
            Invoke(New UpdateText(AddressOf Me.StatusBox.AppendText), response)
        Else
            MsgBox(response)
            Me.StatusBox.AppendText(response)
        End If
    End Sub
    Public Sub PowerOn()
        If Me.StatusBox.InvokeRequired Then
            Me.StatusBox.Invoke(New action(AddressOf PowerOn))
        End If
        Me.StatusBox.BackColor = Color.Blue
    End Sub
    Public Sub SetChannelModes(modesce As String)
       If UserControl11.chModesLabel.InvokeRequired Then
            UserControl11.chModesLabel.Invoke(New Action(Of String)(AddressOf SetChannelModes), modesce)
        Else
            UserControl11.chModesLabel.Text = modesce
        End If
    End Sub
    Public Sub SetChannelTopic(Topicsc As String)
        If UserControl11.chTopicLabel.InvokeRequired Then
            UserControl11.chTopicLabel.Invoke(New Action(Of String)(AddressOf SetChannelTopic), Topicsc)
        Else
            UserControl11.chTopicLabel.Text = Topicsc
        End If
    End Sub

some code from form1 which it links.. uhm i guess i forgot to also say that the form1 is also linked to a Usercontrol1
but as i have said... it all works.. if its all in form1 ...i try to seperate the connection code...and .. it connects..but no updates to the form..

hope someone here will be kind and help thanks
 
You're using Form1 to refer to default form instance from your secondary thread, problem is that will only return you a new form instance for that thread. You need to pass the form instance from UI thread to the class before starting the thread. A different approach where your class doesn't need to know anything about any forms, is to define and raise events from your class, and let the form handle those events including handling threading/invoke itself.
 
As JohnH says, you're using the default instance of your form and that is thread-specific. If you don't know what default instances are then follow the Blog link in my signature and check out my post on the subject. To solve you're problem, you have four main options, two of which JohnH touched on:

1. Presumably a Form1 instance creates the Class1 instance, so you can design Class1 to accept a Form1 reference when it's created and then use that to invoke methods.
2. Like option 1 but put no thread awareness into Class1, so it calls methods directly on the Form1 instance and Form1 handles the invocation.
3. Have Class1 raise events with no thread awareness. Form1 will then handle those events and perform the invocation.
4. Include thread awareness but not form awareness into Class1 using the SynchronizationContext class. Class1 can then raise events on the UI thread and Form1 can handle them.

I would go with one of the last two options.
 
Back
Top