1.C#中创建不带参数的线程:
static void Main(string[] args)
{
Thread th = new Thread(ThreadChild);
th.Start();
Console.WriteLine("Main Thread Start!");
}
static void ThreadChild()
{
Console.WriteLine("Child Thread Start!");
}
2. C#中创建带参数的线程:
创建一个自定义类,在类中定义一个作为传入参数的字段,将线程的主方法定义为一个类的实例方法。然而使用这种方法就可以使用泛型来解决使用ParameterizedThreadStart的类型不安全
class Program
{
static void Main(string[] args)
{
MyThread<string> mThread = new MyThread<string>("Thread_child");
Thread t = new Thread(mThread.ThreadChild);
t.Start();
}
}
class MyThread<T>
{
private T data;
public MyThread(T data)
{
this.data = data;
}
public void ThreadChild()
{
Console.WriteLine("Child Thread Start! Result:{0}",data);
}
}
3.对线程的操作:
(1). 挂起线程
挂起线程使用Suspend()方法。
线程被挂起后,操作被停止或进入休眠状态。
被挂起的线程不占用任何处理器时间。
ThreadStart entry = new ThreadStart(CalcSum);
Thread workThread = new Thread(entry);
workThread.Start();
workThread.Suspend();//挂起线程
此时主线程正常执行,但是工作线程workThread没有被执行,因为工作线程一启动后就被挂起了,所以不会被执行。那么要想工作线程能继续执行,就需要恢复线程了。
(2). 恢复线程
线程恢复使用Resume()方法。
再次修改代码。
Thread workThread = new Thread(new ThreadStart(CalcSum));
workThread.Start();
workThread.Suspend();//挂起线程
Console.WriteLine("Main Thread Start!");
workThread.Resume();//恢复线程
在主线程执行完后,恢复被挂起的工作线程。
(3). 中止线程
中止线程使用Abort()方法。
线程被中止,就停止运行,是无法恢复的,因为Windows会永久地删除被中止线程的所有数据。
再次修改代码。
Thread workThread = new Thread(new ThreadStart(CalcSum));
workThread.Start();
workThread.Abort();//中止线程
Console.WriteLine("Main Thread Start!");
跟挂起工作线程时的结果一样,中止工作线程后,工作线程自然不会被执行。
我们自作聪明一把,尝试着去恢复被中止的线程,看看会有什么样的结果?
修改代码:
Thread workThread = new Thread(new ThreadStart(CalcSum));
workThread.Start();
workThread.Abort();
Console.WriteLine("Main Thread Start!");
workThread.Resume();//恢复线程
运行程序,出现运行时错误,提示:
线程目前未运行;无法使其继续。
这时线程已经被删除,自然无法恢复。
(4). 使线程休眠
使线程休眠使用Sleep()方法(看着就想睡觉)。我们还可以使线程休眠一定的时间,累了就让他歇歇再工作。
示例代码如下:
Thread workThread = new Thread(new ThreadStart(CalcSum));
workThread.Start();
Thread.Sleep(10000);//线程休眠
Console.WriteLine("Main Thread Start!");
这样,主线程会被暂停一段时间后再接着运行,暂停了10000ms。
休眠线程无需恢复,过了指定的时间段会自动恢复运行。
(5). Join()方法等待线程中止
如果后续的处理依赖于另一个已经终止的线程,可以调用Join()方法,等待线程中止。
也可以这么理解 -- MainThread在NewThread.Join被调用后被阻塞(停止执行),直到NewThread 执行完毕才继续执行。
示例代码:
Thread workThread = new Thread(new ThreadStart(CalcSum));
workThread.Start();
workThread.Join();//等待工作线程中止
Console.WriteLine("Main Thread Start!");
工作线程调用了Jion()方法,需待工作线程中止后,主线程才会被执行。
Jion()的其他重载方法可以指定等待的时间期限,超过了这个时间期限,程序也会继续执行。
示例代码:
Thread workThread = new Thread(new ThreadStart(CalcSum));
workThread.Start();
workThread.Join(1000);//等待工作线程中止,1s后主线程(调用/创建这个子线程的父线程)便会开始工作
Console.WriteLine("Main Thread Start!");
主线程会等待一段时间(10000ms),若这段时间内工作线程没挂掉,一旦超过这个时间,主线程便会开始工作。
关于Join比较难理解,特加多个例子说明 :
namespace 多线程
{
public class Simple
{
public static int Main()
{
Console.WriteLine("Thread Start/stop/join sample");
Alpha alpha = new Alpha();
Thread t = new Thread(new ThreadStart(alpha.Beta));
t.Start();
while (!t.IsAlive) Thread.Sleep(1);
t.Abort();
//t.Join();
Console.WriteLine("alpha.Beta 已经结束,执行状态为"+t.IsAlive.ToString()+"线程状态为:"+t.ThreadState.ToString());
try
{
Console.WriteLine("试图重新启动 alpha.Beta");
t.Start();
}
catch(ThreadStateException) {
Console.WriteLine("ThreadStateException 试图重新启动t线程");
Console.WriteLine("t线程终止后不能被重启");
Console.ReadLine();
}
return 0;
}
}
public class Alpha {
public void Beta() {
while (true) {
Console.WriteLine("Alpha.Beta 正在运行");
}
}
}
}
执行结果为:
有时也可能为
由此可看出:
1.abort()的功能是用来终止调用此方法的线程的,只是在多数情况下,它需要一点时间,有些延迟(可能在短时间内此线程还在执行)...
2.join()方法它的功能不是终止线程,而是在t 线程终止之前,阻止正在结束(调用了abort()方法但还未结束)的t 线程执行,同时使主线程等待,直到t线程终止(也就是abort()方法终止过程完毕)了再执行下面的代码,打印出来的结果,执行状态就为FALSE,线程状态也为停止了
注意:在没有调用JOIN方法前,这段代码的执行结果可能为图中两种结果,都会存在,这可能根据电脑的不同,abort()执行时间有关,所以,这里join保证了我们在执行下面的代码时,t 线程实现了“真正”的终止,我想这就是join用在abort()后的妙处吧!
参考 : C#基础:使用Thread创建线程