在一个线程上创建的C#控件不能作为另一个线程上的控件的父级

时间:2013-02-07 12:15:08

标签: c# multithreading user-interface controls

我正在运行一个线程,该线程抓取信息并创建标签并显示它,这是我的代码

    private void RUN()
    {
        Label l = new Label();
        l.Location = new Point(12, 10);
        l.Text = "Some Text";
        this.Controls.Add(l);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Thread t = new Thread(new ThreadStart(RUN));
        t.Start();
    }

有趣的是,我有一个以前的应用程序有一个面板,我曾经使用线程添加控件没有任何问题,但这个不会让我这样做。

3 个答案:

答案 0 :(得分:8)

您无法从其他线程更新UI线程:

 private void RUN()
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke((MethodInvoker)delegate()
                {
                    Label l = new Label(); l.Location = new Point(12, 10);
                    l.Text = "Some Text";
                    this.Controls.Add(l);
                });
            }
            else
            {
                Label l = new Label();
                l.Location = new Point(12, 10);
                l.Text = "Some Text";
                this.Controls.Add(l);
            }
        }

答案 1 :(得分:5)

您需要使用BeginInvoke从另一个线程安全地访问UI线程:

    Label l = new Label();
    l.Location = new Point(12, 10);
    l.Text = "Some Text";
    this.BeginInvoke((Action)(() =>
    {
        //perform on the UI thread
        this.Controls.Add(l);
    }));

答案 2 :(得分:3)

您正在尝试从不同的线程向父控件添加控件,只能从创建父控件的线程中将控件添加到父控件中!

使用Invoke从另一个线程安全地访问UI线程:

    Label l = new Label();
    l.Location = new Point(12, 10);
    l.Text = "Some Text";
    this.Invoke((MethodInvoker)delegate
    {
        //perform on the UI thread
        this.Controls.Add(l);
    });