C# this.invoke()作用 多线程操作UI
程序员文章站
2022-06-10 16:31:00
...
How to: Make Thread-Safe Calls to Windows Forms Controls
如何做到跨线程访问控件呢?
微软官方文档已经写的非常好了,在这里先贴出地址:
下面贴出自己改编的一个小例子:
Demo改编自:cnblogs.com/arxive/p/6739058.html
//测试的窗体
public partial class Form2 : Form
{
//创建一个Button对象
private Button button = new Button();
//构造函数
public Form2()
{
//设置按钮的属性
button.Size = new Size(150, 100); //大小
button.Click += Button2_Clicked; //注册事件
button.Text = "点击开始测试2"; //设置显示文本
this.Controls.Add(button); //添加到窗体上
this.Text = "多线程范例2"; //设置窗体的标题栏文本
}
//按钮的Click事件响应方法
public void Button2_Clicked(object sender, EventArgs e)
{
//启动一个线程,传入委托类型的参数(这里传入的是lambada表达式)
Thread th = new Thread(()=>
{
//this.Invoke就是跨线程访问ui的方法,也是本文的范例
//首先invoke一个Action委托,把lambda表达式赋值给这个委托,将button对象禁用
Action MyAct = () => { button.Enabled = false; };
this.Invoke(MyAct);
//记录一个时间戳,以演示倒计时效果
int tick = Environment.TickCount;
while (Environment.TickCount - tick < 1000)
{
//跨线程调用更新窗体上控件的属性,这里是更新这个按钮对象的Text属性
Action MyAct2 = () => { button.Text = (1000 - Environment.TickCount + tick).ToString() + "微秒后开始更新"; };
this.Invoke(MyAct2);
//做一个延迟,避免太快了,视觉效果不好。
Thread.Sleep(100);
}
//演示,10次数字递增显示
for (int i = 0; i < 10; i++)
{
Action MyAct3 = () => { button.Text = i.ToString(); };
this.Invoke(MyAct3);
Thread.Sleep(200);
}
//虽然不是循环内,请不要忘记,你的调用依然在辅助线程中,所以,还是需要invoke的。
//还原状态,设置按钮的文本为初始状态,设置按钮可用。
Action MyAct4 = () =>
{
button.Text = "点击开始测试";
button.Enabled = true;
};
this.Invoke(MyAct4);
});
th.IsBackground = true;//设置为后台进程(通常要这么设置)
th.Start();
}
}