471,605 Members | 1,501 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,605 software developers and data experts.

Events seem to execute on a new thread - why?

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(DeviceDataEven tHandler);
}

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
Feb 11 '06 #1
4 3317
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


"Erik" wrote:
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(DeviceDataEven tHandler);
}

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

Feb 12 '06 #2
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
Feb 12 '06 #3
Hi Erik,
if you look at the Microsoft documentation for the SerialPort DataReceived
event
http://msdn2.microsoft.com/en-us/lib...areceived.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

"Erik" wrote:
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

Feb 12 '06 #4
I totally missed that detail (obviously). You rock! Much thanks.

Erik
Feb 12 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by Jesper | last post: by
2 posts views Thread by Zürcher See | last post: by
3 posts views Thread by Chris Dunaway | last post: by
9 posts views Thread by CuriousGeorge | last post: by
15 posts views Thread by colin | last post: by
14 posts views Thread by Gotch | last post: by
4 posts views Thread by jehugaleahsa | last post: by
reply views Thread by MichaelMortimer | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.