多线程,访问UI控制

发布于 2024-12-25 17:33:23 字数 507 浏览 0 评论 0原文

我有一个简单的应用程序,带有通常的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夜夜流光相皎洁 2025-01-01 17:33:23

您需要在另一个线程上实际设置 Parent 属性。

LinkLabel l = new LinkLabel();
if (rssFeedPanel.InvokeRequired) {
    rssFeedPanel.Invoke(new MethodInvoker(delegate {
        l.Parent = rssFeedPanel;
    }));
}
else
    l.Parent = rssFeedPanel;

一般来说,几乎所有涉及访问 UI 控件成员的操作都只能从 UI 线程完成。一些明显的例外是 InvokeInvokeRequiredBeginInvoke 以及 BackgroundWorker 类的一些方法。

如果您希望这种情况,也可以使用 BeginInvoke 而不是 Invoke

You need to actually set the Parent property on the other thread.

LinkLabel l = new LinkLabel();
if (rssFeedPanel.InvokeRequired) {
    rssFeedPanel.Invoke(new MethodInvoker(delegate {
        l.Parent = rssFeedPanel;
    }));
}
else
    l.Parent = rssFeedPanel;

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 the BackgroundWorker class.

If you wish for this case, you can also use BeginInvoke instead of Invoke.

血之狂魔 2025-01-01 17:33:23

我建议您将逻辑放在一个方法中,首先检查是否 InvokeRequired 然后在 Invoke 中调用该方法,否则直接调用它。

if (rssFeedPanel.InvokeRequired) {
    rssFeedPanel.Invoke(new MethodInvoker(delegate 
    { 
        AddLabel();
    }));
}
else AddLabel();

并将您的逻辑放入 AddLabel 方法中:

private void AddLabel()
{
    LinkLabel l = new LinkLabel();
    l.Parent = rssFeedPanel;
}

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.

if (rssFeedPanel.InvokeRequired) {
    rssFeedPanel.Invoke(new MethodInvoker(delegate 
    { 
        AddLabel();
    }));
}
else AddLabel();

And put your logic in AddLabel method:

private void AddLabel()
{
    LinkLabel l = new LinkLabel();
    l.Parent = rssFeedPanel;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文