MattMeharry

This problem has to do with updating a control/dataset based on the DataRecevied event of the serial port. Now I know you are thinking cross threading (which it might be) but let me explain.

I have a dataset in the main UI form that is databound to a number of controls. When I change the values of the dataset the bound controls update. This is fine, but when I update the values of the dataset via the DataReceived event the values DON'T update To illlustrate the problem simply I have stripped down the code to it's most basic form. I hope someone can shed some light on the problem.

public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
// create a dataset and populate it with data
UnitDataSet uds = new UnitDataSet();
uds.DIns.ReadXml("Data.xml");

// create a new comms instance and pass a ref to the dataset
_comms = new Comms(uds);

// create a label to bind too
Label lblInputState = new Label();
panel1.Controls.Add(lblInputState);

// databind the control to the state column
lblInputState.DataBindings.Add("Text", uds.Tables["DIns"], "state");
}

// used to test if the binding works and value changes as expected
public void button1_Click(object sender, EventArgs e)
{
_comms.ChangeValue();
}
}

============================================================

class Comms
{
SerialPort _sp;
UnitDataSet _uds;

public Comms(UnitDataSet uds)
{
_uds = uds;
_sp = new SerialPort("COM7", 9600, Parity.None, 8, StopBits.One);
_sp.DataReceived += new SerialDataReceivedEventHandler(_sp_DataReceived);
_sp.Open();
}

private void _sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
// run this method when the event fires
ChangeValue();
}

// if i call this from the main form button (see above ) the value changes but if it's called
// by the above DataReceived event the value doesn't change! !
public void ChangeValue()
{
// simple toggle to change the value
bool tmp = (bool)_uds.Tables["DIns"].Rows[0]["state"];
_uds.Tables["DIns"].Rows[0]["state"] = !tmp;
}
}


Re: Visual C# General Obivous oversite?

TaylorMichaelL

I believe it is a cross-threading issue. Here is how the code will run.

  1. You open the port which will start an async listening on the port. We'll assume it is running in the TP but this doesn't really matter.
  2. When data arrives on the wire the DataReceived event is raised on the TP thread.
  3. Your handler and ultimately the ChangeValue method is called on the TP thread.
  4. You update your data set, again on the TP thread.
  5. When the data set changes it raises its changed event, again on the TP thread.
  6. The UI, which has registered for the change notification, receives it on the TP thread. In an ideal world it'll ignore the request because it is cross-thread but in the worst case it'll mangle the UI.

Michael Taylor - 2/14/07
http://p3net.mvps.org





Re: Visual C# General Obivous oversite?

MattMeharry

Ok, so basicly what you are saying is that the request to change the UI originated from another thread (in this case the from the serial port thread) so it's being ignored/causing the problem Any ideas how to fix it Thanks for your help!!




Re: Visual C# General Obivous oversite?

MattMeharry

I'm not so sure if it's an obvious oversite, but the problem was if it's run in debug mode in the IDE it doesn't work but the built version without the IDE works fine. Thanks to Ed Poore who found out what was happening!