Reputation: 99
I'm trying to add data to DataSet
object from 3 different threads. All threads are System.Threading.Timer
object threads because I'm using 3 separate timers (System.Threading.Timer
type) in the program. After each TimerCallback
delegate is invoked I'm acquiring data from some external PLCs (one timer for each PLC) and trying to put those data to DataSet
. Acquiring data from PLCs works perfect because I'm able to display these data in some
DataGridViews (one DataGridView for each PLC) There is also anotherDataGridView
object (fourth) which should reflect all changes in DataSet
immediately because it is bound to the DataSet. In the end these data I would like to put to database - but that's not a problem right now.
I need the data acquired from PLCs to put in the DataSet
object. Also what I would like to see is watching all changes from DataSet
in DataGridView
right away after those changes take place.
I set the (fourth) DataGridView
object properties as follows :
this.dgvxDataSet.AutoGenerateColumns = true;
this.dgvxDataSet.DataSource = DataSet1.Tables[0];
My code is as follows :
public partial class Form1 : Form
{
DataSet _ds = new DataSet("dataSet1");
System.Threading.Timer timer1;
System.Threading.Timer timer2;
System.Threading.Timer timer3;
private void Form1_Load(object sender, EventArgs e)
{
BuildDataSet();
this.dgvxDataSet.AutoGenerateColumns = true;
this.dgvxDataSet.DataSource = DataSet1.Tables[0];
}
private void BuildDataSet()
{
DataTable table1 = DataSet1.Tables.Add("table1");
table1.Columns.Add("col1", typeof(Int32));
table1.Columns.Add("col2", typeof(Int32));
table1.Columns.Add("col3", typeof(Int32));
table1.Columns.Add("col4", typeof(Int32));
table1.Columns.Add("col5", typeof(DateTime));
table1.Columns.Add("col6", typeof(Int32));
table1.Columns.Add("col7", typeof(Int32));
}
private void btnReadData_Click(object sender, EventArgs e)
{
timer1 = new System.Threading.Timer(new TimerCallback(PoolingStartPLC1), null, 0, Timeout.Infinite);
timer1.Change(0, (int)nudPollingTiming.Value);
timer2 = new System.Threading.Timer(new TimerCallback(PoolingStartPLC2), null, 0, Timeout.Infinite);
timer2.Change(0, (int)nudPollingTiming.Value);
timer3 = new System.Threading.Timer(new TimerCallback(PoolingStartPLC3), null, 0, Timeout.Infinite);
timer3.Change(0, (int)nudPollingTiming.Value);
}
public void PoolingStartPLC1(object state)
{
/*
Acquireing data from PLC1 which works fine
*/
DataRow newRow;
//I'm adding data to DataSet through MethodInvoker() because the DataSet was created in
//the main thread.
this.Invoke(new MethodInvoker(() =>
{
newRow = DataSet1.Tables[0].NewRow();
newRow["col1"] = DataSet1.Tables[0].Rows.Count + 1;
newRow["col2"] = variable11;
newRow["col3"] = variable12;
newRow["col4"] = variable13;
newRow["col5"] = dateTimeVariable1;
}));
}
public void PoolingStartPLC2(object state)
{
/*
Acquireing data from PLC2 which works fine
*/
DataRow newRow;
//I'm adding data to DataSet through MethodInvoker() because the DataSet was created in
//the main thread.
this.Invoke(new MethodInvoker(() =>
{
newRow = DataSet1.Tables[0].NewRow();
newRow["col1"] = DataSet1.Tables[0].Rows.Count + 1;
newRow["col2"] = variable21;
newRow["col3"] = variable22;
newRow["col4"] = variable23;
newRow["col5"] = dateTimeVariable2;
}));
}
public void PoolingStartPLC3(object state)
{
/*
Acquireing data from PLC3 which works fine
*/
DataRow newRow;
//I'm adding data to DataSet through MethodInvoker() because the DataSet was created in
//the main thread.
this.Invoke(new MethodInvoker(() =>
{
newRow = DataSet1.Tables[0].NewRow();
newRow["col1"] = DataSet1.Tables[0].Rows.Count + 1;
newRow["col2"] = variable31;
newRow["col3"] = variable32;
newRow["col4"] = variable33;
newRow["col5"] = dateTimeVariable3;
}));
}
}
After a while the data should be in the DataSet
object but the problem is they are not. During debugging I see empty DataSet
and the DataGridView
ofcourse doesn't display any rows ...
I don't know what am i doing wrong. Interestingly I don't receive any concurrency exceptions associated with adding data to the same DataSet
object from 3 separate threads simultaneously. Maby I should use some locks or something (if any). If yes - I don't know how and where ... But the worst is that I don't know how put the data (which I have) to DataSet
.
I'm using VS2010 Ultimate. The project is Windows forms project.
Thanks
Upvotes: 2
Views: 728
Reputation: 3408
You have to add the row to the DataSet. One would think that .NewRow() adds the row but it doesn't - it just creates a new row that fits that DataSet table. Call DataSet1.Tables[0].Rows.Add(newRow). That should work.
Upvotes: 2