多线程,访问UI控制
我有一个简单的应用程序,带有通常的 UI 线程和后台工作人员,在后台工作人员中,我需要动态创建 LinkLabels 并将它们放置在 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;
I have a simple app with the usual UI thread and a background worker, in the background worker I need to dynamically create LinkLabels and place them in a FlowLayoutPanel. In order to do this I need to set the parent of the LinkLabel to the FlowLayoutPanel.
Here is a snippet of code I currently have, however, I get the infamous "Cross-thread operation not valid" on the line 'l.Parent = panel;'
I'm fairly new to multithreaded operations but I thought I did the invoking correctly, but obviously not. Any Suggestions?
LinkLabel l = new LinkLabel();
if (rssFeedPanel.InvokeRequired) {
FlowLayoutPanel panel = null;
rssFeedPanel.Invoke(new MethodInvoker(delegate { panel = rssFeedPanel; }));
l.Parent = panel;
}
else
l.Parent = rssFeedPanel;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您需要在另一个线程上实际设置
Parent
属性。一般来说,几乎所有涉及访问 UI 控件成员的操作都只能从 UI 线程完成。一些明显的例外是
Invoke
、InvokeRequired
、BeginInvoke
以及BackgroundWorker
类的一些方法。如果您希望这种情况,也可以使用
BeginInvoke
而不是Invoke
。You need to actually set the
Parent
property on the other thread.In general, nearly any operation involving accessing the members of a UI control can only be done from the UI thread. Some obvious exceptions are
Invoke
,InvokeRequired
,BeginInvoke
, and some of the methods of theBackgroundWorker
class.If you wish for this case, you can also use
BeginInvoke
instead ofInvoke
.我建议您将逻辑放在一个方法中,首先检查是否 InvokeRequired 然后在 Invoke 中调用该方法,否则直接调用它。
并将您的逻辑放入 AddLabel 方法中:
I recommend you to put your logic in one method and first check if InvokeRequired then call that method within Invoke otherwise call it directly.
And put your logic in AddLabel method: