VB/C#.net使用后台工作程序动态添加控件项
我正在创建一个Windows窗体应用程序,它根据从数据库中提取的数据动态创建控件 我的代码在后台运行良好,从数据库加载数据并将其应用于变量,我遇到的问题是,当尝试使用此数据创建控件时,我遇到了一个多线程错误(其他信息:跨线程操作无效:从创建控件的线程以外的线程访问控件“flowpanelMenuRules”。) 我正在使用BackgroundWorker\u DoWork事件,失败的代码如下:VB/C#.net使用后台工作程序动态添加控件项,c#,vb.net,multithreading,winforms,C#,Vb.net,Multithreading,Winforms,我正在创建一个Windows窗体应用程序,它根据从数据库中提取的数据动态创建控件 我的代码在后台运行良好,从数据库加载数据并将其应用于变量,我遇到的问题是,当尝试使用此数据创建控件时,我遇到了一个多线程错误(其他信息:跨线程操作无效:从创建控件的线程以外的线程访问控件“flowpanelMenuRules”。) 我正在使用BackgroundWorker\u DoWork事件,失败的代码如下: Me.flowpanelMenuRules.Controls.Add(PanelRule(i)) 前
Me.flowpanelMenuRules.Controls.Add(PanelRule(i))
前面的代码是一个简单的循环,通过变量(从数据库中提取)并收集信息
有人有过安全调用上述代码的经验吗?我似乎根本无法让它工作:(
感谢您的帮助,如果需要,我可以发布更多代码。WinForms应用程序的本机方式是使用和属性等方法访问UI线程:
if(this.flowpanelMenuRules.InvokeRequired)
{
this.flowpanelMenuRules.Invoke(() => AddPanelRule());
}
else
{
AddPanelRule();
}
您还可以使用类
如果您确定位于UI线程上(例如,在一个按钮中单击处理程序),Dispatcher.CurrentDispatcher
为您提供UI线程调度程序,您以后可以使用该调度程序像往常一样从后台线程调度到UI线程
Dispatcher.CurrentDispatcher.Invoke(() => this.flowpanelMenuRules.Controls.Add(PanelRule(i)));
我的建议是让您的BackgroundWorker简单地创建控件,但不要将它们添加到表单中。相反,通过
RunWorkerCompleted
事件将准备好的控件返回到调用/UI线程。然后在此时将控件添加到表单中,可能与SuspendLayout()一起
/ResumeLayout()
方法。请参阅以了解错误原因。控件不应在后台线程上创建。它们被分配到创建它们的线程,并且只应在那里使用。您应该调用控件的特定创建和更新,其余的可以在BGW中完成。您是否可能混合了VB和C?@Rinecamo这个问题是用C#标记提出的,我所有的例子都只包含C#代码。Me
是VB的等价物吗@Rinecamo噢,哇,谢谢,我编辑了我的答案。我认为Me
是属性名。Joel-我使用了这个想法,它工作得非常好。我让后台工作人员现在运行我的SQL代码,将数据库中的信息拉到变量中,然后使用后台工作人员完成的事件在FlowL中填充结果谢谢!我以前使用过后台工作人员,但由于某种原因,我忘记了已完成的活动