如何绑定到另一个线程中填充的数据?
How can I bind to data being populated in another thread?
我有一个后台工作人员用 MyClass
填充 System.Collections.Concurrent.ConcurrentQueue
。然后我有一个 System.ComponentModel.BackgroundWorker
将 ConcurrentQueue
清空到 System.Data.DataTable
。我已经制作了 table public,以便我可以绑定到它以更新 WinForms 图表。但是,我开始意识到 DataTable
不是线程安全的。
我可以用什么代替?我喜欢 DataTable
,因为我可以简单地通过向 MyClass 添加属性来添加列,并且很容易绑定到我的图表。这个问题有没有我遗漏的标准解决方案?
编辑:
我将绘制大量数据(数千个点的数十个),这就是为什么我想使用绑定 - 为了性能。
Form_main.cs:
public Form_main()
{
InitializeComponent();
// ... add some series data
chart_highLevel.DataSource = MyClass.dt; // this being populated in a BackgroundWorker in MyClass
}
private void timer_updateGui_Tick(object sender, EventArgs e)
{
chart_highLevel.DataBind(); // Update the databind
}
MyClass.cs
public DataTable dt = {get; private set;}
private void bw_analyser_DoWork(object sender, DoWorkEventArgs e)
{
while(true)
{
// ... populate 'values'
dt.Rows.Add(values); // values are the data to fill the DataTable, dt
}
}
您必须使用 lock 语句来同步访问同一对象的线程,即您的情况下的数据 table。此外,Data Table 具有克隆,可用于在分配给数据 source.In 之前创建新数据 table 这样,DataBind 操作将使用数据 table ,而数据 table 永远不会由后台线程修改。因此集合被修改的问题将得到解决。
尝试以下更改
private void timer_updateGui_Tick(object sender, EventArgs e)
{
lock(MyClass.dt)
{
chart_highLevel.DataSource = MyClass.dt.Copy();
}
chart_highLevel.DataBind(); // Update the databind
}
public DataTable dt = {get; private set;}
private void bw_analyser_DoWork(object sender, DoWorkEventArgs e)
{
while(true)
{
// ... populate 'values'
lock(dt)
{
dt.Rows.Add(values); // values are the data to fill the DataTable, dt }
}
}
我有一个后台工作人员用 MyClass
填充 System.Collections.Concurrent.ConcurrentQueue
。然后我有一个 System.ComponentModel.BackgroundWorker
将 ConcurrentQueue
清空到 System.Data.DataTable
。我已经制作了 table public,以便我可以绑定到它以更新 WinForms 图表。但是,我开始意识到 DataTable
不是线程安全的。
我可以用什么代替?我喜欢 DataTable
,因为我可以简单地通过向 MyClass 添加属性来添加列,并且很容易绑定到我的图表。这个问题有没有我遗漏的标准解决方案?
编辑: 我将绘制大量数据(数千个点的数十个),这就是为什么我想使用绑定 - 为了性能。
Form_main.cs:
public Form_main()
{
InitializeComponent();
// ... add some series data
chart_highLevel.DataSource = MyClass.dt; // this being populated in a BackgroundWorker in MyClass
}
private void timer_updateGui_Tick(object sender, EventArgs e)
{
chart_highLevel.DataBind(); // Update the databind
}
MyClass.cs
public DataTable dt = {get; private set;}
private void bw_analyser_DoWork(object sender, DoWorkEventArgs e)
{
while(true)
{
// ... populate 'values'
dt.Rows.Add(values); // values are the data to fill the DataTable, dt
}
}
您必须使用 lock 语句来同步访问同一对象的线程,即您的情况下的数据 table。此外,Data Table 具有克隆,可用于在分配给数据 source.In 之前创建新数据 table 这样,DataBind 操作将使用数据 table ,而数据 table 永远不会由后台线程修改。因此集合被修改的问题将得到解决。 尝试以下更改
private void timer_updateGui_Tick(object sender, EventArgs e)
{
lock(MyClass.dt)
{
chart_highLevel.DataSource = MyClass.dt.Copy();
}
chart_highLevel.DataBind(); // Update the databind
}
public DataTable dt = {get; private set;}
private void bw_analyser_DoWork(object sender, DoWorkEventArgs e)
{
while(true)
{
// ... populate 'values'
lock(dt)
{
dt.Rows.Add(values); // values are the data to fill the DataTable, dt }
}
}