A thread and textbox question

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

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
 
Technically, you shouldn't be accessing a control from any other thread
except the one it was created on.
http://msdn.microsoft.com/library/d...ystemwindowsformscontrolclassinvoketopic1.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.
 
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.
 
Back
Top