访问另一个线程内的表单控件

时间:2016-01-17 11:59:25

标签: c# multithreading winforms

我们说,我在Windows窗体上有两个按钮。 当我按下button1时,我在新线程中使用一个名为wh的AutoResetEvent来等待。 当我按下button2时,我会执行wh.Set()以便我的线程被解锁。这是我的课程来说明这一点:

public partial class Form1 : Form
{
    AutoResetEvent wh = new AutoResetEvent(false);
    Thread th;

    public Form1()
    {
        InitializeComponent();
    }

    public void button1_Click(object sender, EventArgs e)
    {
        th = new Thread(thread);
        th.Start();
    }

    public void thread()
    {
        MessageBox.Show("waiting..");
        wh.WaitOne();
        MessageBox.Show("Running..");
    }

    private void button2_Click(object sender, EventArgs e)
    {
        wh.Set();
    }
}

这是按照需要运作的。但我的问题是,我无法访问,让我说出一个标签或任何其他控件,来自我的帖子。

public partial class Form1 : Form
{
    AutoResetEvent wh = new AutoResetEvent(false);

    public Form1()
    {
        InitializeComponent();
    }

    Thread th;

    public void button1_Click(object sender, EventArgs e)
    {
        th = new Thread(thread);
        th.Start();
    }

    public void thread()
    {
        label1.Text = "waiting..";
        wh.WaitOne();
        label1.Text = "running..";
    }

    private void button2_Click(object sender, EventArgs e)
    {
        wh.Set();
    }
}

我运行此错误,说从另一个线程访问label1。

那么如何在第二个线程中访问控件,或者修改我的代码以更改wh.WaitOne的位置,而不阻止主线程? 代码示例表示赞赏!

1 个答案:

答案 0 :(得分:0)

这是因为标签是在不同的线程上创建的,您不能直接更改它。我建议你使用BeginInvoke

 AutoResetEvent wh = new AutoResetEvent(false);
    Thread th;

    private delegate void SetLabelTextDelegate(string text);
    public Form1()
    {
        InitializeComponent();
    }
    public void thread()
    {
        // Check if we need to call BeginInvoke.
        if (this.InvokeRequired)
        {
            // Pass the same function to BeginInvoke,
            this.BeginInvoke(new SetLabelTextDelegate(SetLabelText),
                                             new object[] { "loading..." });
        }
        wh.WaitOne();

    }

    private void SetLabelText(string text)
    {
        label1.Text = text;
    }