一、Thread 类创建线程
线程 System.Threading.Thread 可以创建和控制线程,Thread类的构造函数重载为接受ThreadStart和ParameterizedThreadStart类型的委托参数,由于ParameterizedThreadStart委托的参数类型必须是Object的,所以常用ThreadStart委托,下面简单写下:
static void Main(string[] args)
{
//ThreadStart委托
ThreadStart threadStart = new ThreadStart(() => {
Calculate("Test");
});
Thread thread = new Thread(threadStart);
thread.Start();
//ParameterizedThreadStart委托
ParameterizedThreadStart start2 = new ParameterizedThreadStart(Calculate2);
Thread thread2 = new Thread(start2);
thread2.Start();
}
static void Calculate(string name)
{
}
static void Calculate2(Object obj)
{
}
二、Thread 操作控制线程
1.使用Start()方法使线程处于Running状态,线程开始执行。
static void Main(string[] args)
{
Console.WriteLine($"********************* 系统开始 线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH: mm:ss.fff")} ***************");
ThreadStart threadStart = new ThreadStart(() =>
{
Calculate("Test");
});
Thread thread = new Thread(threadStart);
//线程开始
thread.Start();
Console.WriteLine($"********************* 系统结束 线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH: mm:ss.fff")} ***************");
Console.ReadKey();
}
//公共方法,下面示例代码就不展示了,默认都用这个
static void Calculate(string name)
{
Console.WriteLine($"********************* 线程-{name}开始 线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} ***************");
long num = 0;
for (int i = 0; i < 10000000; i++)
{
num += i;
}
//等待2s
Thread.Sleep(2000);
Console.WriteLine($"********************* 线程-{name}结束 线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} ***************");
}
主线程01直接执行完,不会等待线程03。
2.使用Join()方法使线程处于WaitSleepJoin状态,在继续执行标准的 COM 和 SendMessage 消息泵处理期间,阻塞调用线程,直到某个线程终止或经过了指定时间为止。
static void Main(string[] args)
{
Console.WriteLine($"********************* 系统开始 线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH: mm:ss.fff")} ***************");
ThreadStart threadStart = new ThreadStart(() =>
{
Calculate("Test");
});
Thread thread = new Thread(threadStart);
//线程开始
thread.Start();
//阻塞线程,等待线程完成
thread.Join();
Console.WriteLine($"********************* 系统结束 线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH: mm:ss.fff")} ***************");
}
Join()方法会阻塞线程01,等待线程03完成后才会放行。
3.使用Sleep()方法,也会使线程处于WaitSleepJoin状态,在经历Sleep()方法定义的时间段后,线程就会被再次唤醒。
4. 使用Abort()方法, 在调用此方法的线程上引发System.Threading.ThreadAbortException,以开始终止此线程的过程。 调用此方法通常会终止线程。
Console.WriteLine($"********************* 系统开始 线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH: mm:ss.fff")} ***************");
ThreadStart threadStart = new ThreadStart(() =>
{
Calculate("Test");
});
Thread thread = new Thread(threadStart);
//线程开始
thread.Start();
//线程睡眠等待1s
Thread.Sleep(1000);
//终止线程
thread.Abort();
Console.WriteLine($"********************* 系统结束 线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH: mm:ss.fff")} ***************");
线程在睡眠等待1s后终止,期间线程03在执行,线程03在开始执行一段时间,睡眠等待结束,执行线程03终止,此时线程03可见还未执行结束便被强制终止。
5.IsBackground属性设置线程是否为后台线程,默认是前台线程,UI进程退出后,还会继续执行。
三、Thread 线程状态
简单查看线程是否有效,使用IsAlive便可以查看,但使用ThreadState可以查看更多线程状态的细节,如下表格:
字段 | 状态 | 描述 |
---|---|---|
IsAlive | true | 有效 |
IsAlive | false | 无效 |
ThreadState | Unstarted | 未启用 |
ThreadState | Running | 运行中 |
ThreadState | Aborted | 终止 |