Jump to content
  • Advertisement
Sign in to follow this  
CyberJay82

[.net] C# - Threading and Events Problem

This topic is 3925 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a serial port device which I can get certain information from it, for example a voltage. My problem lies with threading and the end programmer using my events to display the info given to them via the events they subscribe to. I have a public interface which inheirts from my class that actually does the reading from the serial port. This base class has a method that is called each time a voltage is read from the serial port. This is done via a thread that just polls the serial port checking for voltage data. My thread function in a simple form looks like this:
public void TaskFunction()
{
	if(IsVoltageData)
	{
		OnVolts();
	}
}




The OnVolts function looks like this:
protected override void OnVolts()
{
	VoltmeterHandler voltsdata = OnVoltsData;
	if (voltsdata != null)
	{
		voltsdata.Invoke(this, new VoltmeterArgs(GetVoltage()));
	}
}




The end programmer will use my public interface which has the following Event Arguments, delegate, and event:
public class VoltmeterArgs : EventArgs
    {
        public double m_Data;

        public VoltmeterArgs(double data)
        {
            m_Data = data;
        }
    }

public delegate void VoltmeterHandler(object sender, VoltmeterArgs e);

public event VoltmeterHandler OnVoltsData;




Now that end programmer would hook up to that event (OnVoltsData) and use it for example to display the voltage to the user via a textbox or something. Here lies my problem. When ever I do this in my test app:
public void VoltMeter_OnVoltsData(object sender, VoltmeterArgs e)
{
     txtVoltage.Text = e.m_Data.ToString();
}




I still get this error: "Cross-thread operation not valid: Control 'txtVoltage' accessed from a thread other than the thread it was created on." I guess I am missing something or don't understand something. I thought when you invoked the event it would then fire the event on the thread it was created on. Any ideas, options, links, information I can read to help sort this issue I am having out?

Share this post


Link to post
Share on other sites
Advertisement
This is an error that was introduced in VS2005 and can actually be disabled so that it will compile. However, it's better to actually go with the solution: you can't access controls from a thread other than the one on which they are created. When you invoke the event delegate, the listeners are invoked on the current thread.

The solution, thankfully is simple.

public void VoltMeter_OnVoltsData(object sender, VoltmeterArgs e)
{
if (txtVoltage.InvokeRequired)
txtVoltage.Invoke(VoltMeter_OnVoltsData(sender, e));
else
txtVoltage.Text = e.m_Data.ToString();
}


In this case, however, rather than playing with threads directly, you may be better off using a BackgroundWorker and handling its RunWorkerCompleted event (you pass your data in the Result field of RunWorkerCompletedEventArgs).

EDIT: Closed missed bracket for function call, added supplementary links.

Share this post


Link to post
Share on other sites
Sorry, I should say it compiles and runs, but throws an exception with that error.

I know that using invoke on the textbox control would be a solution, but I was hoping to hide that from the end programmer and just allow them to use the textbox control like normal by just setting it's text.

Share this post


Link to post
Share on other sites
Quote:
Original post by CyberJay82
Sorry, I should say it compiles and runs, but throws an exception with that error.


Sorry, I wasn't very accurate. This would require considerable analysis of the code to produce a compile-time error; I mean that the error was introduced with that version of .NET (2.0?).

Quote:
I know that using invoke on the textbox control would be a solution, but I was hoping to hide that from the end programmer and just allow them to use the textbox control like normal by just setting it's text.


About your easiest option then, as I and the above poster have said, is to use a BackgroundWorker.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!