C#线程从陌生到熟悉(2)
首先我们来看看线程的状态
线程状态
表1-1 ThreadState定义的枚举常数
|
成员名称 |
说 明 |
|
Aborted |
线程处于Stopped状态中 |
|
AbortRequested |
已对线程调用了Thread.Abort方法,但线程尚未收到试图终止它的挂起的System.Threading. ThreadAbortException |
|
Background |
线程正作为后台线程执行(相对于前台线程而言)。此状态可以通过设置Thread.IsBackground属性来控制 |
|
Running |
线程已启动,它未被阻塞,并且没有挂起的ThreadAbortException |
|
Stopped |
线程已停止 |
|
StopRequested |
正在请求线程停止。这仅用于内部 |
|
Suspended |
线程已挂起 |
|
SuspendRequested |
正在请求线程挂起 |
|
Unstarted |
尚未对线程调用Thread.Start方法 |
|
WaitSleepJoin |
由于调用Wait、Sleep或Join,线程已被阻止 |
Thread对象的ThreadState属性提供一个由ThreadState定义的位掩码,它指示线程的当前状态。一个线程至少总是处于ThreadState枚举中定义的一个可能状态,并且可以同时处于多个状态。
注意,只能在一些调试方案中使用线程状态,而不应该在代码中使用线程状态来同步线程活动。
在创建托管线程时,该线程处于Unstarted状态。线程会保持Unstarted状态,直到被操作系统调度到已启动状态。调用Start方法使操作系统知道该线程可启动,但是它并不直接更改线程的状态。一旦线程处于已启动的状态中,就可以执行许多操作来使线程更改状态。表1-2列出了使状态发生更改的操作,以及相应的新状态。
表1-2 使线程状态发生更改的操作及相应的新状态
|
操 作 |
ThreadState |
|
在公共语言运行库中创建线程 |
Unstarted |
|
线程调用Start |
Unstarted |
|
线程开始运行 |
Running |
续表
|
操 作 |
ThreadState |
|
线程调用Sleep |
WaitSleepJoin |
|
线程对其他对象调用Wait |
WaitSleepJoin |
|
线程对其他线程调用Join |
WaitSleepJoin |
|
另一个线程调用Interrupt |
Running |
|
另一个线程调用Suspend |
SuspendRequested |
|
线程响应Suspend请求 |
Suspended |
|
另一个线程调用Resume |
Running |
|
另一个线程调用Abort |
AbortRequested |
|
线程响应Abort请求 |
Stopped |
|
线程被终止 |
Stopped |
Abort方法,调用该方法后,在当前线程中引发一个ThreadAbortException异常,该异常导致线程死亡!线程进入Stopped状态,不能在重启!
请看下面的例子
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
Thread t1 = new Thread(Print);
// t1.Abort();引发ThreadAbortException异常
t1.Start();
// t1.Abort();
//t1.Join();阻塞调用线程,直到某个线程终止时为止。
Console.WriteLine("主线程被调用");
// t1.Start();引发ThreadAbortException异常无法重新启动
}
static void Print()
{
Thread.Sleep(2000);
Console.WriteLine("线程被调用!");
}
}
}
从这个例子中,我们可以看出,线程处于Unstarted状态时,调用Abort()方法时,将引发异常!
将第二个注释打开,得到如下结果

线程被终止了!把第四个注释打开,又会引发异常!
在这里我要说明下Join()这个方法,将第三个注释打开,会得到如下结果,

Join这个方法的作用是阻塞调用他的线程,换句话说就是调用他的线程处于阻塞状态,直到这个线程执行结束,调用他的线程才继续执行!这里调用他的线程指的是主线程!
Interrupt 该方法打断一个处于WaitSleepJoin状态的线程。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
Thread t1 = new Thread(Print);
t1.Start();
Thread.Sleep(500);
t1.Interrupt();
Thread.Sleep(500);
Console.WriteLine("主线执行结束!");
}
static void Print()
{
try
{
Thread t2=new Thread(Print2);
t2.Start();
t2.Join();
}
catch (Exception e)
{
Console.WriteLine("捕获到异常:{0}", e.ToString());
}
Console.WriteLine("线程1运行!");
}
static void Print2()
{
Thread.Sleep(2000);
Console.WriteLine("线程2运行!");
}
}
}
运行结果为

从中可以看出线程1调同线程2的方法时被打断了,以致于线程1直接运行了!这个就是Interrupt得作用!如果将Interrupt这个方法给注释掉,那就会看到线程2运行完了,线程1才继续运行!Interrupt 该方法打断一个处于WaitSleepJoin状态的线程。应该可以理解了吧!
好了,这次就到这里了!
浙公网安备 33010602011771号