1.在clr中Thread这个名字来表示线程这个概念
本篇文章讲解Thread的实例方法:【id,ThreadState】
2.如何管理Thread的生命周期
Start
Suspend
Resume
Interupt
Abort
(另外还有Join使用很多)
上面5种,在Thread的使用过程中非常多。
例子:实现生命周期中的方法
我们可以实现一个每隔一秒,在TextBox中追加数字的效果
点击开始时,每隔1s,追加数字,并加1
创建window项目,编辑界面,添加TextBox和5个按钮
Thread thread = null;
int index = 0;
1)开始事件:
///
/// 开启线程
///
///
///
private void button1_Click(objectsender, EventArgs e)
{
thread = new Thread(newThreadStart(() =>
{
while (true)
{
try
{
Thread.Sleep(1000);
textBox1.Invoke(newAction(() =>
{
textBox1.AppendText(string.Format("{0}", index++));
}));
}
catch (Exception ex)
{
MessageBox.Show(string.Format("{0},{1}", ex.Message,index));
throw;
}
}
}));
thread.Start();
}
2)暂停事件:
///
/// 暂停
///
///
///
private void button2_Click(objectsender, EventArgs e)
{
//在启动或者休眠期间可进行暂停
if(thread.ThreadState==ThreadState.Running ||thread.ThreadState==ThreadState.WaitSleepJoin)
thread.Suspend();//已经弃用了
}
点击开始,然后再点击暂停,我们可以在此时使用windbg来查看thread的状态
打开windbg32位,File->Attachto a Process
可以看到有一个后台线程,BackgroundThread:1,总共是3个线程
执行!clrstack查看CLR堆栈
可以点击下图中的State(第三个是主线程),可以看到状态信息。
显示信息
退出windbg。
3)恢复Resume:将挂起的线程重新启动
///
/// 恢复挂起的线程
///
///
///
private void button3_Click(objectsender, EventArgs e)
{
if (thread.ThreadState ==ThreadState.Suspended)
{
thread.Resume();
}
}
4)中断Interrupt:用来中断处于WaitSleepJoin状态的线程。
就像
While(true){
Continue ….效果
}
的效果
但是,当你调用interrupt的时候,会抛出一个interrput的异常。
抛出异常后,while循环仍然继续执行。
所以,如果打印了1,2,3之后中断,那么打印的4大概需要4秒(2+2秒休眠时间)
5)Abort
通过抛出异常的方式销毁一个线程,终止次线程。那么,线程后面的操作就不会再执行了。停止后,TextBox就停在3上了。
可以看出Abort和Interrupt之间的区别
此时,使用windbg附加进程,加载sos,clr,查看线程
可以看到此时的主线程抛出了AbortException
重新开启window程序,启动-》中止
如果将弹出框(正在中止线程)关闭,那么线程就关闭了
打开windbg附加进程,可以看到线程死了,并且主线程的OSID没了,说明已经销毁。
点击状态下的数字:
常用的方法:Join:
例子:
创建一个控制台程序:
class Program
{
static void Main(string[] args)
{
Thread t = new Thread(newThreadStart(() =>
{
Thread.Sleep(1000);
Console.WriteLine("子线程执行完毕");
}));
t.Start();
t.Join();//调用线程等待子线程执行完之后才执行。。。【在此等待子线程执行完毕】
Console.WriteLine("主线程执行完毕");
Console.Read();
}
}
执行,t.Join(),那么主线程必须等待子线程t执行完毕后,才能继续向后执行。相当于阻塞主线程。
执行结果:
如果不加t.Join();那么主线程会先执行完毕。
将上述的休眠时间调长,使用windbg,查看这个睡眠的线程能否被中断:
可以看到,这是一个可中断的线程