如果不用子线程,下面的代码可以完全正常的工作。不管点击button1,或者Button2都能正常在文本框中显示Hello.
private void button1_Click(object sender, EventArgs e)
{
setText();
}
private void button2_Click(object sender, EventArgs e)
{
setText();
}
private void setText()
{
textBox1.Text = "Hello";
}
但是,如果在Button2中另起一个子线程,访问textBox1,就会出现异常。
private void button1_Click(object sender, EventArgs e)
{
setText();
}
private void button2_Click(object sender, EventArgs e)
{
Thread t = new Thread(new ThreadStart(setText));
t.Start();
}
private void setText()
{
textBox1.Text = "Hello";
}
为了实现在子线程中对窗体控件的访问,需要使用系统提供的Invoke方法,代码如下。
delegate void SetTextDelegate();
private void button1_Click(object sender, EventArgs e)
{
setText();
}
private void button2_Click(object sender, EventArgs e)
{
Thread t = new Thread(new ThreadStart(setText2));
t.Start();
}
private void setText()
{
textBox1.Text = "Hello";
}
private void setText2()
{
Invoke(new SetTextDelegate(setText));
}
C#中还提供了this.InvokeRequired这个属性,来判断对控件的访问是主线程,还是子线程。应用这个属性,可以在button1_Click 和button2_Click中都统一用setText2,但是需要在setText2中增加一个判断,判断是主线程还是子线程的访问,代码如下。
private void button1_Click(object sender, EventArgs e)
{
setText2();
}
private void button2_Click(object sender, EventArgs e)
{
Thread t = new Thread(new ThreadStart(setText2));
t.Start();
}
private void setText()
{
textBox1.Text = "Hello";
}
private void setText2()
{
if (this.InvokeRequired) //如果是子线程,需要用代理访问。
{
Invoke(new SetTextDelegate(setText));
}
Else //否则直接访问。
{
setText();
}
}
没有评论:
发表评论