问题描述
我有winForm项目,它有一个dataGridView,它绑定到一个从workerThread更新的dataTable。当我在workerThread上更新我的dataTable时,我使用dataGridView.BeginInvoke()。我这样做是为了处理任何交叉线程问题并防止阻塞。我还有一个winForm timerControl,每秒触发一次并对我的dataTable进行一些清理操作。
我的问题是,我的dataTable正在更新来自和来自的数据workerThread并使用timerControl清理mainThread我在这里有线程问题吗?
示例:
I have winForm project that has a dataGridView that's bound to a dataTable that's updated from a workerThread. When I update my dataTable on the workerThread I use dataGridView.BeginInvoke(). I do this to handle any cross threading issues and to prevent blocking. I also have a winForm timerControl that fires every second and does some clean operations on my dataTable.
My question is, by my dataTable being updated with data from and on the workerThread and cleaned up on the mainThread with the timerControl am I having threading issues here?
Example:
class Form1: Form
{
MyDataCls myDatCls;
DataGridView grid;
DataTable dataTbl;
Timer tmr;
public Form1()
{
grid = new DataGridView();
dataTbl = new DataTable();
DataColumn col;
col = new DataColumn();
col.ColumnName = "Time"
dataTbl.Columns.Add(col);
col = new DataColumn();
col.ColumnName = "Name"
dataTbl.Columns.Add(col);
col = new DataColumn();
col.ColumnName = "Addrs"
dataTbl.Columns.Add(col);
grid.DataSource = dataTbl;
myDataCls = new MyDataCls();
myDataCls.PushData += new PushDataEvntHndlr(myDataCls_PushData);
tmr = new Timer();
tmr += new Timer(tmr_Tick);
tmr.Interval = 1000;
tmr.Start();
}
// this is the handler I use to receive data that
// comes from a workerThread
private void myDataCls_PushData(string[] someData)
{
if(grid.InvokeRequired)
{
DataRow row = dataTbl.NewRow();
grid.BeginInvoke(new MethodInvoker(delegate()
{
row["Time"] = someData[0];
row["Name"] = someData[1];
row["Addrs"] = someData[2];
dataTbl.Rows.Add(row);
}));
}
else
{
row["Time"] = someData[0];
row["Name"] = someData[1];
row["Addrs"] = someData[2];
dataTbl.Rows.Add(row);
}
}
// this is the timer handler that does the cleanup
private void tmr_Tick(object sender, EventArgs e)
{
if (dataTbl.Rows.Count > 0)
{
foreach (DataRow row in dataTbl.Select())
{
if (row["Name"] == "Joe Doe")
row["Name"].Delete();
}
}
}
}
推荐答案
private void myDataCls_PushData(string[] someData)
{
if (grid.InvokeRequired)
{
var pushAction = new Action<string[]>(myDataCls_PushData);
grid.Invoke(pushAction, someData);
}
else
{
DataRow row = dataTbl.NewRow();
row["Time"] = someData[0];
row["Name"] = someData[1];
row["Addrs"] = someData[2];
dataTbl.Rows.Add(row);
}
}
这篇关于GUI跨线程操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!