Mah*_* KP 6 datagridview backgroundworker thread-safety bindingsource winforms
我们绑定一个DataGridview使用BindingSource.所以在我们这样给出的主线程中.
class1BindingSource = new BindingSource();
class1BindingSource.DataSource = class1List;
this.dataGridView1.DataSource = class1BindingSource;
Run Code Online (Sandbox Code Playgroud)
之后,我在窗体中放置了一个后台工作器,并在单击按钮时触发.
即在按钮单击中
this.backgroundWorker1.RunWorkerAsync()
Run Code Online (Sandbox Code Playgroud)
在BackgroundWorker DoWork Event我试图BindingSource通过尝试更新来更新和那里DataGridview.
因此,BindingSource重置是在另一个类的方法中完成的.
DoWork Event
Class2 cl2 = new Class2();
cl2.UpdateBindingSource(class1BindingSource);
Run Code Online (Sandbox Code Playgroud)
UpdateBindingSource Method
public void UpdateBindingSource(BindingSource bs)
{
Class1 c1 = bs.Current as Class1;
for (int i = 0; i < 1000; i++)
{
lock (bs.SyncRoot)
{
c1.MyProperty1 = i;
bs.ResetItem(0);
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我得到一个例外,就像BindingSource它不能成为自己的数据源一样.不要将DataSource和DataMember属性设置为引用的值BindingSource.
如果我在我这样做,我DoWork Event可以使用重置控制线程本身的项目BeginInvoke method.
但实际上我正在尝试模拟我们的应用场景.所以我想以这种格式解决这个问题.
谁可以帮我这个事.
Oli*_*ver 15
问题是你不能BindingSource在gui线程之外的另一个线程内更新.这是因为BindingSource会触发一些事件,这些事件随后将被您的数据网格视图接收,然后这些事件将开始自我更新,这将失败,因为它不会在gui线程上完成.
因此,在你打电话之前,RunWorkerAsync()你应该打电话class1BindingSource.SuspendBinding()给RunWorkerCompleted你class1BindingSource.ResumeBinding().
还要确保在DoWork你的内容中不会调用绑定源上的任何方法(就像你所做的那样bs.ResetItem(0)).
并删除此锁定语句.它只是没有任何意义(在你的例子中),如果你真的需要它(在你的真实代码中)考虑private object _Gate = new Object();在你的类中使用一些来避免来自外部世界的任何死锁,原因bs.SyncRoot是公开可用的.
| 归档时间: |
|
| 查看次数: |
11088 次 |
| 最近记录: |