Serial communication simple problem
Hi All,
I'm trying to write my first serial communication app in VB.net 2005 and I keep getting this error message:
Cross-thread operation not valid: Control 'ListBox1' accessed from a thread other than the thread it was created on.
I know it has something to do with delegates but I have no idea how to use it in my code. Your help would be very much appreciated
Code:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If Button1.Text Is "Open Port" Then
SerialPort1.Open()
Button1.Text = "Close Port"
Button2.Enabled = True
ElseIf Button1.Text Is "Close Port" Then
SerialPort1.Close()
Button1.Text = "Open Port"
Button2.Enabled = False
End If
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
SerialPort1.WriteLine(TextBox1.Text)
TextBox1.Text = ""
ListBox1.Items.Add(TextBox1.Text)
End Sub
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
ListBox1.Items.Add(SerialPort1.ReadLine()) <--------------This is where I get the error message
End Sub
End Class
Re: Serial communication simple problem
Thats because the DataReceived event is raised on a separate thread. As of .NET 2.0, you can not access a control from a different thread than the thread that the control was created on without performing a safe cross-thread call.
Here's how it must look:
VB.NET Code:
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
AddListItem(SerialPort1.ReadLine())
End Sub
Private Delegate Sub AddListItemCallBack(ByVal text As String)
Private Sub AddListItem(ByVal text As String)
If ListBox1.InvokeRequired Then 'Returns True if execution is NOT made on the thread that ListBox1 was created on.
ListBox1.Invoke(New AddListItemCallBack(AddListItem), text) 'Invoke this method again, in the correct thread.
Else
ListBox1.Items.Add(text)
End If
End Sub
Re: Serial communication simple problem
Thanks for the quick reply Atheist
I'll try it out and play around with it a bit more.
Re: Serial communication simple problem
I now get this error message:
'SpApp.Form1.AddListItemCallBack' is a delegate type and requires a single 'addressof' expression as the only argument to the constructor.
Code:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If Button1.Text Is "Open Port" Then
SerialPort1.Open()
Button1.Text = "Close Port"
Button2.Enabled = True
ElseIf Button1.Text Is "Close Port" Then
SerialPort1.Close()
Button1.Text = "Open Port"
Button2.Enabled = False
End If
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
SerialPort1.WriteLine(TextBox1.Text)
TextBox1.Text = ""
ListBox1.Items.Add(TextBox1.Text)
End Sub
'Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
' ListBox1.Items.Add(SerialPort1.ReadLine())
'End Sub
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
AddListItem(SerialPort1.ReadLine())
End Sub
Private Delegate Sub AddListItemCallBack(ByVal text As String)
Private Sub AddListItem(ByVal text As String)
If ListBox1.InvokeRequired Then 'Returns True if execution is NOT made on the thread that ListBox1 was created on.
ListBox1.Invoke(New AddListItemCallBack(AddListItem), text) 'Invoke this method again, in the correct thread. <------This is where the error is
Else
ListBox1.Items.Add(text)
End If
End Sub
End Class
Re: Serial communication simple problem
Oh I'm sorry I was thinking in C# when i wrote that code. The line should look like this:
vb Code:
ListBox1.Invoke(New AddListItemCallBack(AddressOf AddListItem), text)
Re: Serial communication simple problem
As a warning, if you got data constantly streaming in on your serial port, such as from a weight scale, the DataReceived event is glitchy. Many times it won't fire in these instances.
Re: Serial communication simple problem
Really sorry guys...the program now runs....but when I try to send data, it gives me an error message saying TimeoutException was unhandled the operation has timed out
Code:
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
AddListItem(SerialPort1.ReadLine())
End Sub
Private Delegate Sub AddListItemCallBack(ByVal text As String)
Private Sub AddListItem(ByVal text As String)
If ListBox1.InvokeRequired Then 'Returns True if execution is NOT made on the thread that ListBox1 was created on.
ListBox1.Invoke(New AddListItemCallBack(AddressOf AddListItem), text) 'Invoke this method again, in the correct thread.
Else
ListBox1.Items.Add(text)
End If
End Sub
End Class
Re: Serial communication simple problem