jared Posted December 30, 2006 Posted December 30, 2006 Hi all! I am working on an app using VB.Net 2005 Express. I am receiving data from the serial port and simply updating a few labels with the data I receive. I am using MethodInvoker to invoke a method that simply reads the data from the serial port buffer and updates the values on a few labels. If I am receiving data faster than I can update the UI (there is more data in the receive buffer to process) and try to close the application it hangs. I'm guessing this is because the SerialPort component has fired a bunch of DataReceived events which created a long list of methods to invoke. Here is my DataReceived event and Method that is called via the MethodInvoker... Private Sub SerialPort1_DataReceived _ (ByVal sender As Object, _ ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _ Handles SerialPort1.DataReceived ' If we receive any character then... If e.EventType = IO.Ports.SerialData.Chars Then ' If we have received at least two bytes then ' Create a MethodInvoker and call ProcessData Dim MI As MethodInvoker MI = New MethodInvoker(AddressOf ProcessData) Invoke(MI) End If End Sub Private Sub ProcessData() ' Crate a place to store the two bytes Dim Data(1) As Byte ' Create a place to store the 16 bit result Dim Result As Integer ' Read the first two bytes in the buffer ' into our array named Data SerialPort1.Read(Data, 0, 2) ' Combine the bytes to create a 16 bit word value Result = CInt((Data(0) * &H100&) Or Data(1)) ' Display the result lblPressure.Text = "Pressure Value = " & Result.ToString If Result > 60000 Then lblAlarm.Text = "Pressure to high!" lblAlarm.ForeColor = Color.Red ElseIf Result >= 10000 Then lblAlarm.Text = "Pressure normal." lblAlarm.ForeColor = Color.Black Else lblAlarm.Text = "Pressure too low!" lblAlarm.ForeColor = Color.Blue End If End Sub End Class I have tried commenting out all of the code in the ProcessData sub and the problem still occurs. I have removed the MethodInvoker code and simply displayed the data to the debug window from the DataReceived event and there is no problem. The problem is definitely related to the cross thread call. I found one workaround, but it is not predictable... If I add a Application.DoEvents in the Form_Closing event sometimes the application will shut down correctly. I think it matters how many events are in the message que though. Sometimes it may take two or three Application.DoEvents to successfuly allow the application to close. Just matters how long I let the app run before I try to close it. Any idea of how to fix this problem? Thanks, Jared Quote
Leaders snarfblam Posted December 30, 2006 Leaders Posted December 30, 2006 What you want to do is call the Form.Invoke method on the Form that you want to update. The Form.Invoke method ensures that the method being invoked is processed on the application's main thread. [Color=Blue]Private Sub[/Color] SerialPort1_DataReceived _ ([Color=Blue]ByVal [/Color]sender [Color=Blue]As [/Color]Object, _ [Color=Blue]ByVal [/Color]e [Color=Blue]As [/Color]System.IO.Ports.SerialDataReceivedEventArgs) _ [Color=Blue]Handles [/Color]SerialPort1.DataReceived [Color=Green]' If we receive any character then... [/Color] [Color=Blue]If [/Color]e.EventType = IO.Ports.SerialData.Chars [Color=Blue]Then[/Color] SomeFormThatContainsLabels.Invoke( _ [Color=Blue][Color=Blue]AddressOf [/Color][/Color]ProcessData) [Color=Blue] End If End Sub[/Color][/Code] Haven't tested that, but it should at least give you an idea. Quote [sIGPIC]e[/sIGPIC]
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.