我有一个简单的应用程序,通常的UI线程和后台工作者,在后台工作器中我需要动态创建LinkLabel并将它们放在FlowLayoutPanel中。为此,我需要将LinkLabel的父级设置为FlowLayoutPanel。
这是我目前拥有的代码片段,但是,我在“l.Parent = panel;”
行上得到了臭名昭着的“跨线程操作无效”我对多线程操作相当新,但我认为我正确地进行了调用,但显然没有。有什么建议吗?
LinkLabel l = new LinkLabel();
if (rssFeedPanel.InvokeRequired) {
FlowLayoutPanel panel = null;
rssFeedPanel.Invoke(new MethodInvoker(delegate { panel = rssFeedPanel; }));
l.Parent = panel;
}
else
l.Parent = rssFeedPanel;
答案 0 :(得分:3)
您需要在另一个线程上实际设置Parent
属性。
LinkLabel l = new LinkLabel();
if (rssFeedPanel.InvokeRequired) {
rssFeedPanel.Invoke(new MethodInvoker(delegate {
l.Parent = rssFeedPanel;
}));
}
else
l.Parent = rssFeedPanel;
通常,几乎所有涉及访问UI控件成员的操作都只能从UI线程完成。一些明显的例外是Invoke
,InvokeRequired
,BeginInvoke
以及BackgroundWorker
类的一些方法。
如果您希望遇到这种情况,也可以使用BeginInvoke
代替Invoke
。
答案 1 :(得分:3)
我建议你把逻辑放在一个方法中,首先检查InvokeRequired是否在Invoke中调用该方法,否则直接调用它。
if (rssFeedPanel.InvokeRequired) {
rssFeedPanel.Invoke(new MethodInvoker(delegate
{
AddLabel();
}));
}
else AddLabel();
并将您的逻辑放在AddLabel方法中:
private void AddLabel()
{
LinkLabel l = new LinkLabel();
l.Parent = rssFeedPanel;
}