Cross Threading error????

  • Thread starter Thread starter Terry Olsen
  • Start date Start date
T

Terry Olsen

I run this code:
Private Sub p_recv(ByVal sender As Object, ByVal e As
SerialReceivedEventArgs) Handles p.ReceivedEvent
txtRecv.Text += p.ReadExisting
End Sub

I get this error:

--------------------ERROR TEXT--------------------
Illegal cross-thread operation: Control 'txtRecv' accessed from a thread
other than the thread it was created on.
Stack trace where the illegal operation occurred was:

at System.Windows.Forms.Control.get_Handle()
at System.Windows.Forms.Control.get_WindowText()
at System.Windows.Forms.TextBoxBase.get_WindowText()
at System.Windows.Forms.Control.get_Text()
at System.Windows.Forms.TextBoxBase.get_Text()
at System.Windows.Forms.TextBox.get_Text()
at ComPortTest.Form1.p_recv(Object, SerialReceivedEventArgs)
at System.IO.Ports.SerialPort.CatchReceivedEvents(Object,
SerialReceivedEventArgs)
at System.IO.Ports.SerialStream.EventLoopRunner.CallReceiveEvents(Object)
at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object)
at System.Threading.ExecutionContext.Run(ExecutionContext, ContextCallback,
Object, StackCrawlMark&)
at System.Threading._ThreadPoolWaitCallback.WaitCallback(Object)
---------------END ERROR TEXT-----------------------

Evidently, the function I'm calling creates a thread. So how can I write to
the textbox from the function without getting this error?
 
Hey thanks! That helped. Here's the code that works.

Private Delegate Sub TextBoxInvoker(ByVal txt As String)

Private Sub p_recv(ByVal sender As Object, ByVal e As
SerialReceivedEventArgs) Handles p.ReceivedEvent
Dim txt As String = p.ReadExisting
txtRecv.Invoke(CType(AddressOf UpdateTextBox, TextBoxInvoker), txt)
End Sub

Private Sub UpdateTextBox(ByVal txt As String)
txtRecv.Text += txt
End Sub
 
Hey thanks! That helped. Here's the code that works.

Private Delegate Sub TextBoxInvoker(ByVal txt As String)

Private Sub p_recv(ByVal sender As Object, ByVal e As
SerialReceivedEventArgs) Handles p.ReceivedEvent
Dim txt As String = p.ReadExisting
txtRecv.Invoke(CType(AddressOf UpdateTextBox, TextBoxInvoker), txt)
End Sub

Private Sub UpdateTextBox(ByVal txt As String)
txtRecv.Text += txt
End Sub

That's one way, or you can just invoke your method again...

Private Sub p_recv (ByVal sender As Object, ByVal e As
SerialRecievedEventArgs) Handles p.ReceivedEvent

If txtRecv.InvokeRequired Then
txtRecv.Invoke (AddressOf p_recv, new Object() {sender, e})
Else
txtRecv.Text += p.ReadExisting
End If
End Sub
 
I also just discovered the "TextBox.AppendText" method. More elegant than
TextBox.Text += "NewText"
 
Hello Tom. I was trying your method in the following code, but I get this
error in design time;
"'AddressOf' expression cannot be converted to 'System.Delegate' because
'System.Delegate' is not a delegate type"
Any Ideas??? Also, would this even work? It seems as if it might be trying
to read data into myBuffer twice (2nd time when the invoke occurrs).
Thanks!

Private Sub myListener_DataArrival() Handles myListener.DataArrival
Debug.Print("DataArrival Event")
Dim myBuffer() As Byte = New Byte() {}
myListener.ReadData(myBuffer)
If txtReceive.InvokeRequired Then
txtReceive.Invoke(AddressOf myListener_DataArrival) 'Error
occurrs here.
Else
txtReceive.AppendText(System.Text.Encoding.ASCII.GetString(myBuffer))
End If
End Sub
 
Hello Tom. I was trying your method in the following code, but I get this
error in design time;
"'AddressOf' expression cannot be converted to 'System.Delegate' because
'System.Delegate' is not a delegate type"
Any Ideas??? Also, would this even work? It seems as if it might be trying
to read data into myBuffer twice (2nd time when the invoke occurrs).
Thanks!

Private Sub myListener_DataArrival() Handles myListener.DataArrival
Debug.Print("DataArrival Event")
Dim myBuffer() As Byte = New Byte() {}
myListener.ReadData(myBuffer)
If txtReceive.InvokeRequired Then
txtReceive.Invoke(AddressOf myListener_DataArrival) 'Error
occurrs here.
Else
txtReceive.AppendText(System.Text.Encoding.ASCII.GetString(myBuffer))
End If
End Sub

First of all... Are you using one of the standard .NET classes? Because
none of those have a DataArrival event that I recall. I use this
technique all the time for async and multithreaded calls, so I know it
works..

Anyway, part of the problem would be your structure as well... You
would want to move the code that does the reading inside the else block:

If txtRecieve.InvokeRequired Then
' invoke the method
Else
' dim your buffer
' read the data
' append the text
End If
 
Tom,

I'm trying to use this code...but I'm having some problems.

I'm trying to call a Button.PerformClick method from an event handler that
is called from another thread.

Private Sub ConnectionDroppedEvent() Handles myListener.ConnectionDropped
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top