I have a form with a text box, a thread start button, and a seperate thread.
This is a TCP listener (server) example I took out of a book. See the code
below. In the loop below, look at the two lines I have marked with a comment
of ??????? If I don't write to the text box, I have a fast response. The
value "returnedData" is written to the console in a timely manner. However,
if I try to write to the textbox, tbStatus, the response slows to about 1
time per second. Is there some problem with writing to a textbox from within
a seperate thread?? Can somesone suggest a solution.
Hamil.
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnStart.Click
btnStart.Enabled = False
btnStop.Enabled = True
Dim tr As New Thread(AddressOf ListenToClients)
tr.Start()
End Sub
Sub ListenToClients()
'localhostAddress = IPAddress.Loopback
localhostAddress = IPAddress.Parse("192.168.1.5")
port = CInt(txtPort.Text)
tcpList = New TcpListener(localhostAddress, port)
tcpList.Start()
listening = True
Do While listening
Do While tcpList.Pending = False And listening = True
Thread.Sleep(10)
Loop
If Not listening Then Exit Do
Dim tcpCli As New TcpClient
tcpCli = tcpList.AcceptTcpClient()
ns = tcpCli.GetStream
sr = New StreamReader(ns)
sw = New StreamWriter(ns)
tbStatus.Text = "connected"
Do While listening = True
Thread.Sleep(10)
receivedData = sr.ReadLine
If receivedData <> Nothing Then
returnedData = ProcessInput(receivedData)
Console.WriteLine(returnedData) '???????????
tbStatus.Text = returnedData '???????????????
sw.WriteLine(returnedData)
sw.Flush()
End If
Loop
sr.Close()
sw.Close()
ns.Close()
tcpCli.Close()
tbStatus.Text = "closed"
Loop
tcpList.Stop()
End Sub
Imran Koradia - 27 Oct 2004 20:09 GMT
Technically, you shouldn't be accessing a control from any other thread
except the one it was created on.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlr
fsystemwindowsformscontrolclassinvoketopic1.asp
Accessing controls from a secondary thread is not guaranteed. It might work
sometimes but you shouldn't rely on it.
Instead, you should define a delegate and use the delegate to marshal the
calls from the secondary thread to the main thread when accessing your
controls. I'm not sure if this would speed up the update but here's how you
would update a textbox's text from another thread:
Delegate Sub SetTextDelegate(ByVal sText As String)
Private SetText As New SetTextDelegate(AddressOf SetTextBoxText)
Private Sub SetTextBoxText(ByVal sText As String)
tbStatus.Text = sText
End Sub
Sub ListToClients()
...
' all your relevant code..
...
...
...
' replace tbStatus.Text = "Connected" with this..
tbStatus.Invoke(SetText, New Object() {"Connected"})
...
' all your remaining code..
...
...
End Sub
hope that helps..
Imran.
> I have a form with a text box, a thread start button, and a seperate thread.
> This is a TCP listener (server) example I took out of a book. See the code
[quoted text clipped - 54 lines]
> tcpList.Stop()
> End Sub
hamil - 27 Oct 2004 23:07 GMT
What you say works! I tried it. Thanks.
Now, if the text box I want to write into is in another form, how would I
handle this?
I would assume I would do something like..
dim RemoteTextBox as textbox
Private Sub SetTextBoxText(ByVal sText As String)
RemoteTextBox.Text = sText
End Sub
I would have to set the RemotTextBox object variable from the remote form.
Comments??
hamil.
> Technically, you shouldn't be accessing a control from any other thread
> except the one it was created on.
[quoted text clipped - 94 lines]
> > tcpList.Stop()
> > End Sub