我试图从3个不同的线程向DataSet
对象添加数据。所有线程都是System.Threading.Timer
个对象线程,因为我在程序中使用了3个独立的定时器(System.Threading.Timer
类型)。在调用每个TimerCallback
委托之后,我从一些外部PLC(每个PLC一个计时器)获取数据并尝试将这些数据放入DataSet
。从PLC获取数据非常有效,因为我能够在某些数据中显示这些数据
DataGridViews(每个PLC一个DataGridView)还有另一个DataGridView
对象(第四个),它应该立即反映DataSet
中的所有更改,因为它绑定到DataSet。最后,我想将这些数据放到数据库中 - 但这不是现在的问题。
我需要从PLC获取的数据放入DataSet
对象。此外,我希望看到在发生这些更改后立即DataSet
DataGridView
查看所有更改。
我按如下方式设置(第四个)DataGridView
个对象属性:
this.dgvxDataSet.AutoGenerateColumns = true;
this.dgvxDataSet.DataSource = DataSet1.Tables[0];
我的代码如下:
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;
}));
}
}
一段时间后,数据应该在DataSet
对象中,但问题是它们不是。在调试过程中,我看到空DataSet
,而DataGridView
的课程没有显示任何行......
我不知道自己做错了什么。有趣的是,我没有收到任何与同时从3个独立线程向同一个DataSet
对象添加数据相关的并发异常。 Maby我应该使用一些锁或其他东西(如果有的话)。如果是的话 - 我不知道如何以及在哪里......但最糟糕的是,我不知道如何将数据(我拥有的)放到DataSet
。
我正在使用VS2010 Ultimate。该项目是Windows表单项目。
由于
答案 0 :(得分:2)
您必须将行添加到DataSet。有人会认为.NewRow()添加了行但它没有 - 它只是创建一个适合该DataSet表的新行。调用DataSet1.Tables [0] .Rows.Add(newRow)。这应该有用。