多线程+委托的安全访问(invoke)
1.声明方法
2.声明委托类型
3.创建委托对象
4.启动线程
5.在线程调用的方法里通过Control的Invoke方法执行委托
public Form1()
{
InitializeComponent();
//TextBox.CheckForIllegalCrossThreadCalls = false;//线程访问控件(不安全的方式)
dgShowMsgInTextBox = new DGShowMsgInTextBox(DoShowMsgInTextBox);
}
private void btnCount_Click(object sender, EventArgs e)
{
Count();
}
private void Count()//用UI计数(不另外开启线程)
{
DateTime beginTime = DateTime.Now;
for (int i = 0; i < 999999999; i++) { }
System.Threading.Thread.Sleep(3000);
DateTime endTime = DateTime.Now;
TimeSpan ts = endTime.Subtract(beginTime);
MessageBox.Show("计算完毕,总耗时:" + ts.TotalMilliseconds.ToString());
}
private void btnCountByThread_Click(object sender, EventArgs e)//用线程计数
{
//创建线程对象(传入委托对象),也可以直接传方法
Thread thread = new Thread(Count);
thread.Name = "t1";
//将线程标记为可以开始了
thread.Start();
}
private void button1_Click(object sender, EventArgs e)//不安全的访问控件
{
Thread threa = new Thread(CountAndShow);
threa.Start();
}
private void CountAndShow()//不安全的方式访问控件-需要设置TextBox.CheckForIllegalCrossThreadCalls = false
{
DateTime beginTime = DateTime.Now;
for (int i = 0; i < 10000000; i++)
{
txtNum.Text = i.ToString();
}
DateTime endTime = DateTime.Now;
TimeSpan ts = endTime.Subtract(beginTime);
MessageBox.Show("计算完毕,总耗时:" + ts.TotalMilliseconds.ToString());
}
private void CountAndShowSafety()//安全的访问UI线程上的控件
{
DateTime beginTime = DateTime.Now;//记录开始时间
for (int i = 0; i < 10000000; i++)
{
//调用Control类的Invoke方法 执行委托里的 方法
this.Invoke(dgShowMsgInTextBox, i.ToString());
}
DateTime endTime = DateTime.Now;//记录结束时间
TimeSpan ts = endTime.Subtract(beginTime);//计算时间差
MessageBox.Show("计算完毕,总耗时:" + ts.TotalMilliseconds.ToString());
//Random r = new Random();
//r.Next(10)
}
private void button2_Click(object sender, EventArgs e)//安全的访问控件 需要使用委托,并最终通过Control的Invoke方法执行
{
Thread tread = new Thread(CountAndShowSafety);
tread.Start();
}
delegate void DGShowMsgInTextBox(string msg);//安全访问控件的代码 声明一个委托类型
DGShowMsgInTextBox dgShowMsgInTextBox = null;//声明该委托的一个对象(在窗体的构造函数中实例化的),在线程执行代码中要访问控件时通过Invoke方法调用
void DoShowMsgInTextBox(string msg)
{
txtNum.Text = msg;
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace 多线程_委托
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//3.2在窗体加载的时候用‘写的方法DoShoumsgintextbox()’来实例化委托
dgshoumsgintextbox = new DGDoshoumsgintextbox(DoShoumsgintextbox);
}
//4要调用的方法
private void AddString()
{
DateTime beginTime = DateTime.Now;
for (int i = 0; i < 100000; i++)
{
//txtNum1.Text = i.ToString();不能用这个方法给txtnum赋值
///必须用control的invoke方法
this.Invoke(dgshoumsgintextbox, i.ToString());
}
DateTime endTime = DateTime.Now;
TimeSpan ts = endTime.Subtract(beginTime);
MessageBox.Show(ts.Milliseconds.ToString());
}
private void button1_Click(object sender, EventArgs e)
{
//添加Thread的引用
Thread th = new Thread(AddString);
th.Start();
}
//1.申明方法
void DoShoumsgintextbox(string s)
{
txtNum1.Text = s;
}
//2申明委托
delegate void DGDoshoumsgintextbox(string dgs);
//3.1实例化委托1
DGDoshoumsgintextbox dgshoumsgintextbox = null;
}
}