"BindingSource不能是它自己的数据源" - 尝试从另一个类中的方法重置绑定源时出错

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它不能成为自己的数据源一样.不要将DataSourceDataMember属性设置为引用的值BindingSource.

如果我在我这样做,我DoWork Event可以使用重置控制线程本身的项目BeginInvoke method.

但实际上我正在尝试模拟我们的应用场景.所以我想以这种格式解决这个问题.

谁可以帮我这个事.

Oli*_*ver 15

问题是你不能BindingSource在gui线程之外的另一个线程内更新.这是因为BindingSource会触发一些事件,这些事件随后将被您的数据网格视图接收,然后这些事件将开始自我更新,这将失败,因为它不会在gui线程上完成.

因此,在你打电话之前,RunWorkerAsync()你应该打电话class1BindingSource.SuspendBinding()RunWorkerCompletedclass1BindingSource.ResumeBinding().

还要确保在DoWork你的内容中不会调用绑定源上的任何方法(就像你所做的那样bs.ResetItem(0)).

并删除此锁定语句.它只是没有任何意义(在你的例子中),如果你真的需要它(在你的真实代码中)考虑private object _Gate = new Object();在你的类中使用一些来避免来自外部世界的任何死锁,原因bs.SyncRoot是公开可用的.