Events seem to execute on a new thread - why?

E

Erik

First, I am not creating any new threads via invoke or any other intentional
means. As far as I know, there is just one thread, which is the main
thread.

My windows form class creates a new DeviceController() object which
initializes a serial port and defines a serial port event handler, which
processes the raw data from the serial port and then generates my custom
event (OnNewData).

public partial class LoggerForm : Form
{
DeviceController myDevice;

public LoggerForm()
{
InitializeComponent();
myDevice = new DeviceController();
myDevice.OnNewData += new
DeviceController.DeviceDataDelegate(DeviceDataEventHandler);
}

void DeviceDataEventHandler(object sender, DeviceDataEventArgs e)
{
logTextBox.Text = e.DeviceData;
}


The consumer for my custom event is DeviceDataEventHandler(), which fires as
it should but produces the following run-time error: "Cross-thread operation
not valid: Control 'logTextBox' accessed from a thread other than the thread
it was created on."

How could this be? I thought an event was run on the same thread that
created it. It almost seems like the event is handled on a new thread.

Any ideas on why this is happening?


Thanks in advance.
Erik
 
G

Guest

Hi Erik,
the important point is that controls should only be access from the thread
which created them. Your serial port listener is running on a seperate
thread, when data comes in it raises the event, now an event is nothing but
syntactic sugar around a multicast delegate, so the thread that received the
data is really looping through all of the event handlers in the delegates
InvocationList and calling the methods one by one, so it is not the GUI
thread running the handler it is another thread.

In your GUI code you should call invoke i.e. logTextBox.Invoke to make
sure the Main UI thread executes the update to the textbox, not the calling
thread. Also if you are performing some significant amount of processing in
the event handler you should probably use BeginInvoke rather than Invoke, to
allow the serial port handler to get back to receiving data.

Hope that helps
Mark Dawson
http://www.markdawson.org
 
E

Erik

Mark, that does help - I can probably solve it now.

But the basic question I'm grappling with is: why is my serial port
listener running on a separate thread in the first place? I never created a
new thread explicitly. The only thing I did as part of a method in
DeviceController is:

// create SerialPort, open COM port, add Serial Port event handler.
theSerialPort.DataReceived += new
SerialDataReceivedEventHandler(SerialDataParser);

SerialDataParser() just parses the serial port data and fires my
DeviceDataEventHandler() event. I don't understand see how this code is
running on a separate thread. I should mention this is with VS2005 and the
..NET framework 2.0.

Erik
 
G

Guest

Hi Erik,
if you look at the Microsoft documentation for the SerialPort DataReceived
event
http://msdn2.microsoft.com/en-us/library/system.io.ports.serialport.datareceived.aspx
(watch the wrapping) it says that the DataReceived event will be raised on a
secondary thread:

"The DataReceived event is raised on a secondary thread when data is
received from the SerialPort object. Because this event is raised on a
secondary thread, and not the main thread, attempting to modify some elements
in the main thread, such as UI elements, could raise a threading exception.
If it is necessary to modify elements in the main Form or Control, post
change requests back using Invoke, which will do the work on the proper
thread."

Internally inside the SerialPort object, multiple threads are being
utilized, that is why even though you are not explicitly creating a new
thread, it is being done behind the scenes. This is a common pattern for
receiving data, there should be one thread whos job it is to receive data and
it should not spend much time processing the data, so that it can go back to
receive more data, so normally another thread is utilized to handle the data
received on the first thread.

Hope that helps
Mark Dawson
http://www.markdawson.org
 

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

Top