C#跨线程访问控件
线程实现两个lable标签显示:
public partial class FrmThreadControl : Form { public FrmThreadControl() { InitializeComponent(); } private void btnExecute1_Click(object sender, EventArgs e) { int a = 0; Thread objThread1 = new Thread(delegate() { for (int i = 1; i <= 20; i++) { a += i; if (this.lblResult1.InvokeRequired)//判断是否调用Invoke方法 { this.lblResult1.Invoke(new Action<string>(s => { this.lblResult1.Text = s; }), a.ToString()); } Thread.Sleep(200); } }); objThread1.IsBackground = true;//设置为后台线程(通常都要这样设置) objThread1.Start(); } private void btnExecute2_Click(object sender, EventArgs e) { int a = 0; Thread objThread2 = new Thread(() => { for (int i = 1; i <= 50; i++) { a += i; if (this.lblResult2.InvokeRequired)//判断是否调用Invoke方法 { this.lblResult2.Invoke(new Action<string>(s => { this.lblResult2.Text = s; }), a.ToString()); } Thread.Sleep(100); } }); objThread2.IsBackground = true; objThread2.Start(); } }
异步实现计算方法:
public partial class FrmCalllBack : Form { public FrmCalllBack() { InitializeComponent(); //【3】初始化委托变量 // this.objMyCal = new MyCalculator(ExecuteTask); //也可以直接使用Lambda表达式 this.objMyCal = (num, ms) => { System.Threading.Thread.Sleep(ms); return num * num; }; } //【3】创建委托变量(因为异步函数和回调函数都要用,所以定义成成员变量) private MyCalculator objMyCal = null; //【4】同时执行多个任务 private void btnExec_Click(object sender, EventArgs e) { //发布任务 for (int i = 1; i < 11; i++) { //开始异步执行 objMyCal.BeginInvoke(10 * i, 1000 * i, MyCallBack, i); //最后一个参数i给回调函数的字段AsyncState赋值,如果数据很多可以定义成类或结构 } } //【5】回调函数 private void MyCallBack(IAsyncResult result) { int res = objMyCal.EndInvoke(result); //显示异步调用结果:result.AsyncState字段用来封装回调函数自定义参数,object类型 Console.WriteLine("第{0}个计算结果为:{1}", result.AsyncState.ToString(), res); } //【2】根据委托定义一个方法:返回一个数的平方 private int ExecuteTask(int num, int ms) { System.Threading.Thread.Sleep(ms); return num * num; } //【1】声明委托 private delegate int MyCalculator(int num, int ms); } //异步编程的总结: //1. 异步编程是建立在委托的基础上一种编程的方法。 //2. 异步调用的每个方法都是在独立的线程中执行的。因此,本质上就是一种多线程程序,是简化的多线程。 //3. 比较适合在后台运行较为耗时的《简单任务》,并且任务之间要求相互独立,任务中不应该有直接访问可视化控件大代码。 //4. 如果后台任务要求必须按照特定顺序执行,或者访问共享资源,则异步编程不太适合,应选择多线程开发技术。 }
多线程Thread的基础使用:
public partial class FrmThead : Form { public FrmThead() { InitializeComponent(); } //执行任务1 private void btnExecute1_Click(object sender, EventArgs e) { int a = 0; //ThreadStart 委托定义:public delegate void ThreadStart() Thread objThread1 = new Thread(delegate() { for (int i = 1; i <= 20; i++) { a += i; Console.WriteLine(a + " "); Thread.Sleep(500); } }); objThread1.IsBackground = true;//设置为后台线程(通常都要这样设置) objThread1.Start(); } //执行任务2 private void btnExecute2_Click(object sender, EventArgs e) { Thread objThread2 = new Thread(() => { for (int i = 1; i <= 50; i++) { Console.WriteLine("---------------a" + i + "----------------"); Thread.Sleep(100); } }); objThread2.IsBackground = true;//设置为后台线程(通常都要这样设置) objThread2.Start(); } } }