解决控件跨线程访问的问题
public partial class MainFrm : Form
{
public MainFrm()
{
InitializeComponent();
//解决跨线程访问无效方式
//方法一:称之为-掩耳盗铃方法
// 真正项目中绝对不能这么做
//Control.CheckForIllegalCrossThreadCalls = false;//关闭跨线程访问检测
//方法二:
}
private void btnLoop_Click(object sender, EventArgs e)
{
//测试线程开启一个循环
//主线程是UI线程,勉强可以理解为界面线程
//这是一种实现方式:
//Thread thread = new Thread(this.PrintCurrentTime);
//通过lambda表达式方式实现
Thread thread = new Thread(() =>
{
//此处写法会导致跨线程访问异常,线程间访问无效
//原因是:UI界面控件,是由UI线程操控的,但是被新开启的线程访问了,导致跨线程访问无效的异常
//解决办法有两种:
//this.txtTime.Text = DateTime.Now.ToString();
while (true)
{
//解决跨线程访问无效第二种方式
if (!this.txtTime.InvokeRequired)
{
this.txtTime.Text = DateTime.Now.ToString();
}
//作用:InvokeRequired-如果是别的线程创建的此控件,则为true
//Invoke找到 创建 这个控件的 线程 去执行相应的操作,也就是避开子线程去访问主线程控件
this.txtTime.Invoke(new Action<string>(s => this.txtTime.Text = s), DateTime.Now.ToString());//委托类的基类
Console.WriteLine(DateTime.Now.ToString());
Thread.Sleep(1000);
}
});
//设置为后台线程后,关闭主窗口,thread线程同时跟着被关闭;false时主窗口关闭,thread线程仍然在执行
thread.IsBackground = true;
thread.Start();
}
//摘要:
//说明:供应线程调用
private void PrintCurrentTime()
{
while (true)
{
Console.WriteLine(DateTime.Now.ToString());
Thread.Sleep(1000);
}
}
}
点击显示当前时间按钮