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

Winforms &引用;BindingSource不能是自己的数据源";-尝试从另一个类中的方法重置绑定源时出错,winforms,datagridview,thread-safety,backgroundworker,bindingsource,Winforms,Datagridview,Thread Safety,Backgroundworker,Bindingsource,我们正在使用BindingSource绑定一个DataGridview。所以在主线程中,我们给出了如下内容 class1BindingSource = new BindingSource(); class1BindingSource.DataSource = class1List; this.dataGridView1.DataSource = class1BindingSource; 之后,我在表单中放置了一个后台工

我们正在使用
BindingSource
绑定一个
DataGridview
。所以在主线程中,我们给出了如下内容

            class1BindingSource = new BindingSource();
            class1BindingSource.DataSource = class1List;  
            this.dataGridView1.DataSource = class1BindingSource;
之后,我在表单中放置了一个后台工作程序,并通过单击按钮触发

i、 e.在按钮中单击

this.backgroundWorker1.RunWorkerAsync()
BackgroundWorker
DoWork事件中
我试图更新
BindingSource
,并尝试更新
DataGridview

因此,
BindingSource
reset是在另一个类的方法中完成的

DoWork事件

UpdateBindingSource方法

public void UpdateBindingSource(BindingSource-bs)
{
Class1 c1=bs。电流为Class1;
对于(int i=0;i<1000;i++)
{
锁(bs.SyncRoot)
{
c1.MyProperty1=i;
b.第(0)项;
}
}
}
现在我得到了一个异常,比如
BindingSource
不能是它自己的数据源。不要将
DataSource
DataMember
属性设置为引用
BindingSource
的值

如果我在我的
DoWork事件中执行此操作
,那么我可以使用
BeginInvoke方法
重置控制线程本身中的项

但实际上,我正在尝试模拟我们的应用程序场景。所以我想用这种形式来解决这个问题


有人能帮我吗。

问题是除了gui线程之外,您不能在其他线程中更新
BindingSource
。这是因为,
BindingSource
将触发一些事件,然后数据网格视图将接收这些事件,然后数据网格视图将开始自我更新,这将失败,因为它不会在gui线程上执行

因此,在调用
RunWorkerAsync()
之前,应该调用
classbindingsource.SuspendBinding()
,并在
RunWorkerCompleted
中调用
classbindingsource.ResumeBinding()

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

并删除此lock语句。它只是没有任何意义(在你的例子中),如果你真的需要它(在你的真实代码中)考虑使用一些<代码>私有对象,{门=新对象();code>在您的类中,为了避免来自外部世界的任何死锁,因为
bs.SyncRoot
是公开可用的。

我遇到了相同的问题: -具有INotifyPropertyChanged元素的BindingSource -更新元素的单独任务

建议的解决方案SuspendBinding等不起作用。BindingSource应该执行类似IsInvokeRequired的操作

幸运的是,Ivan Stoev想出了一个绝妙的主意,将BindingSource子类化,并按照IsInvoke的要求做一些类似的事情。谢谢你,伊万

链接:

UpdateBindingSource()
不需要花费太多时间,因此无需使用
backgroundworker
。您可以在主线程中调用
UpdateBindingSource()

另外,将datagridview操作保留在主线程中。

因此,我在哪里更新绑定源,在哪里通过重新绑定gridview?我知道在尝试从另一个线程(即不是从UI线程)更新数据源时会导致错误。是否有任何方法可以从此方法调用或调用gridview.BeginInvoke?我想这也可以解决问题。@mahesh:移除
bs.ResetItem()
调用;将
c1.MyProperty1=i'封装到一个
Invoke()`调用中。但这可能会导致其他问题,因为您正在两个线程之间稳步跳跃。因此,最好挂起绑定源,在后台执行这些操作,并在绑定完成后恢复绑定。抱歉,我不明白,如何将c1.MyPropert1=i封装到调用中。因为整个过程都在另一个类中。另外,如果我删除ResetItem(),那么它将如何重新绑定gridview?
Class2 cl2 = new Class2();
cl2.UpdateBindingSource(class1BindingSource);
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);
                }
            }
        }