Explanation of this code?

ejleiss

Active member
Joined
Oct 1, 2012
Messages
37
Programming Experience
1-3
Hi, could someone please explain what this code means is some detail.

Private Sub ReceivedText(ByVal [text] As String)
'compares the ID of the creating Thread to the ID of the calling Thread
If Me.rtbReceived.InvokeRequired Then
Dim x As New SetTextCallback(AddressOf ReceivedText)
Me.Invoke(x, New Object() {(text)})
Else
Me.rtbReceived.Text &= [text]
End If
End Sub

Right now I am receiving "string characters" from a serial port and displaying them in rtbReceived (text box), however
my main goal is to somehow convert this function to read the string and convert the data into hex format before it displays
in rtbReceived.

Is it correct to try to do this in this function, or should it be done in SerialPort1_DataReceived?

Any help would be greatly appreciated.
Thank you.
 
The issue is that the DataReceived event is raised on a secondary thread, therefore the DataRecieved event handler is executed on a secondary thread, while all UI access must be done on the UI thread. That code is crossing the thread boundary in order to update the UI.

The InvokeRequired property of a control tells you whether you can access that control directly here and now or you must call Invoke in order to access it. When InvokeRequried is True it means that you must call Invoke to access the control because the current code is not executing on the thread that the control was created on. If InvokeRequired is False it means that you're executing on the thread that owns that control so you can access it directly.

When you call that method from the DataReceived event handler it will first test InvokeRequired and find that it's True because you're on a secondary thread. It will then enter the If block and create a SetTextCallback delegate, which is an object that refers to a method, and calls Invoke. The Invoke method carries the delegate across the thread boundary to the thread that owns the control it was called on and then invokes it, which calls the method it refers to. That second time the method is called occurs on the UI thread so this time InvokeRequired is False. Execution then enters the Else block and sets the Text of the RichTextBox. To be clear, the method is executed twice: once on the secondary thread and once on the UI thread.

Note that, while it doesn't actually affect the way it works in this, and almost all, cases, it's not good form to use the InvokeRequired property of one control and the Invoke method of another. Generally speaking, all your controls are going to be owned by the same main thread so the result is all the same, but it's considered good practice to use the InvokeRequired and Invoke members of the same control all the same.

Note that the purpose of this method is to cross the thread boundary and, ideally, that's all it should do. If you need to convert data to text first, that should be done in another method; either the DataReceived event handler or some other method you call in between. That said, given that you can read text directly from a SerialPort, do you actually need to convert anything?
 
Back
Top