一 private void button1_Click(object sender, EventArgs e)
{
CountTime();
}
//准备方法给线程调用
void CountTime()
{
for (int i = 0; i < 999999999; i++)
{
}
MessageBox.Show("循环完毕!");
}
//使用多线程来解决UI卡死问题
private void button2_Click(object sender, EventArgs e)
{
//创建线程对象 传入 要线程执行的方法
Thread threadFirst = new Thread(CountTime);
threadFirst.Start();
}
二、 产生一个线程的4个步骤:
1 编写产生线程所需要执行的方法
2 引用System.Threading命名空间
3 实例化Thread类,并传入一个指向线程所需要运行方法的委托(这个时候线程已经产生,但是海没有运行)
4 调用Thread实例的Start方法,标记该线程可以被CPU执行了,但具体执行时间又CPU决定
三 前台线程和后台线程
前台线程:只有所有的前台线程都关闭才能完成程序关闭
后台线程:只要所有的前台线程结束,后台线程自动结束
//使用多线程来解决UI卡死问题
private void button2_Click(object sender, EventArgs e)
{
//创建线程对象 传入 要线程执行的方法
Thread threadFirst = new Thread(CountTime);
//将线程设置为后台线程
threadFirst.IsBackground=true;
threadFirst.Start();
}
四 线程 方法重入问题
线程间操作无效: 从不是创建控件“textBox1”的线程访问它。
//关闭 当前窗体 对废话跨线程访问 修改文本框控件的 检查
TextBox.CheckForIllegalCrossThreadCalls = false;
void ChangeTxt()
{
lock (this)
{
for (int i = 0; i < 1000; i++)
{
int a = int.Parse(textBox1.Text);
a++;
textBox1.Text = a.ToString();
}
}
}
//方法重入问题
private void button3_Click(object sender, EventArgs e)
{
Thread thread = new Thread(ChangeTxt);
thread.IsBackground = true;
thread.Start();
Thread thread2 = new Thread(ChangeTxt);
thread.IsBackground = true;
thread2.Start();
}
不加lock 两个线程会有CPU分配调用执行 加上后会先调用的线程执行完后才会由第二个线程去执行
五 Thread类的一些重要成员
Start()启动线程
Abort()终止线程
Thread.Sleep(1) 静态方法,可以使当前线程停止一段时间运行
Name 线程名
Thread.CurrentThread获得当前的线程引用
六 模拟线程内部结构
//模拟线程
public class MyThread
{
//------------不带参数------------
ThreadStart threads;//定义全局变量
public MyThread(ThreadStart ts)//要求用户在 实例化new的时候传入方法委托
{
this.threads = ts;//将委托 赋给全局变量
}
public void Start()
{
threads();//调用委托,执行委托里的方法
}
//--------------带参数------------
ParameterizedThreadStart pts;//定义全局变量
public MyThread(ParameterizedThreadStart pts)//要求用户在 实例化new的时候传入方法委托
{
this.pts = pts;//将委托 赋给全局变量
}
public void Start( object o)
{
pts(o);//调用委托,执行委托里的方法
}
}
//调用模拟多线程
MyThread mth = new MyThread(CountTime);
//执行带参数方法
void ShowTxtName(object name)
{
if (name!=null)
{
MessageBox.Show("name=" + name.ToString());
}
else
{
MessageBox.Show("null");
}
}
private void button4_Click(object sender, EventArgs e)
{
Thread thread = new Thread(ShowTxtName);//必须为object类型参数
thread.IsBackground = true;
thread.Start(textBox2.Text);//传入object参数 public void Start(object parameter);
}
//线程 执行带多个参数方法
void ShowTxtName2(object li)
{
List<string >list=li as List<string >;
if (list!=null)
{
foreach (string s in list)
{
MessageBox.Show(s);
}
}
}
private void button5_Click(object sender, EventArgs e)
{
Thread thread5 = new Thread(ShowTxtName2);
thread5.IsBackground = true;
thread5.Start(new List<string>() {"刘德华","王力宏","那英" });
}
七 线程的调度方式
1 非抢占式调度:指某个线程在运行时不会被操作系统强制暂停,它可以持续的运行直至运行告一段落并主动地交出运行权。在这样的调度模式下,线程的运行就是完全的单队列的,并且可能产生恶意程序长期霸占运行权的情况。而且一旦一个程序死了,那么只能重启电脑
2 抢占式调度:每个线程都只有极少的运行时间,而当时间用完时该线程就会被强制暂停,保存上下文(线程寄存器中)并把CPU运行权交给下一个线程,这样调度的结果就是所有的线程都在被快速地切换运行,使得使用者觉得所有的线程在“并行”的运行。