1、概念
1.0 线程的和进程的关系以及优缺点
windows系统是一个多线程的操作系统。一个程序至少有一个进程,一个进程至少有一个线程。进程是线程的容器,一个C#客户端程序开始于一个单独的线程,CLR(公共语言运行库)为该进程创建了一个线程,该线程称为主线程。例如当我们创建一个C#控制台程序,程序的入口是Main()函数,Main()函数是始于一个主线程的。它的功能主要 是产生新的线程和执行程序。C#是一门支持多线程的编程语言,通过Thread类创建子线程,引入using System.Threading命名空间。
多线程的优点:
1、 多线程可以提高CPU的利用率,因为当一个线程处于等待状态的时候,CPU会去执行另外的线程
2、 提高了CPU的利用率,就可以直接提高程序的整体执行速度
多线程的缺点:
1、线程开的越多,内存占用越大
2、协调和管理代码的难度加大,需要CPU时间跟踪线程
3、线程之间对资源的共享可能会产生可不遇知的问题
1.1 前台线程和后台线程
C#中的线程分为前台线程和后台线程,线程创建时不做设置默认是前台线程。即线程属性IsBackground=false。
Thread.IsBackground = false;//false:设置为前台线程,系统默认为前台线程。
区别以及如何使用:
这两者的区别就是:应用程序必须运行完所有的前台线程才可以退出;而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时都会自动结束。一般后台线程用于处理时间较短的任务,如在一个Web服务器中可以利用后台线程来处理客户端发过来的请求信息。而前台线程一般用于处理需要长时间等待的任务,如在Web服务器中的监听客户端请求的程序。
线程是寄托在进程上的,进程都结束了,线程也就不复存在了!
只要有一个前台线程未退出,进程就不会终止!即说的就是程序不会关闭!(即在资源管理器中可以看到进程未结束。)
1.3 多线程的创建
下面的代码创建了一个子线程,作为程序的入口mian()函数所在的线程即为主线程,我们通过Thread类来创建子线程,Thread类有 ThreadStart 和 ParameterizedThreadStart类型的委托参数,我们也可以直接写方法的名字。线程执行的方法可以传递参数(可选),参数的类型为object,写在Start()里。
class Program
{
//我们的控制台程序入口是main函数。它所在的线程即是主线程
static void Main(string[] args)
{
Thread thread = new Thread(ThreadMethod); //执行的必须是无返回值的方法
thread.Name = "子线程";
//thread.Start("王建"); //在此方法内传递参数,类型为object,发送和接收涉及到拆装箱操作
thread.Start();
Console.ReadKey();
}
public static void ThreadMethod(object parameter) //方法内可以有参数,也可以没有参数
{
Console.WriteLine("{0}开始执行。", Thread.CurrentThread.Name);
}
}
首先使用new Thread()创建出新的线程,然后调用Start方法使得线程进入就绪状态,得到系统资源后就执行,在执行过程中可能有等待、休眠、死亡和阻塞四种状态。正常执行结束时间片后返回到就绪状态。如果调用Suspend方法会进入等待状态,调用Sleep或者遇到进程同步使用的锁机制而休眠等待。具体过程如下图所示:
2、线程的基本操作
线程和其它常见的类一样,有着很多属性和方法,参考下表:
2.1 线程的相关属性
我们可以通过上面表中的属性获取线程的一些相关信息,下面是代码展示和输出结果:
static void Main(string[] args)
{
Thread thread = new Thread(ThreadMethod); //执行的必须是无返回值的方法
thread.Name = "子线程";
thread.Start();
StringBuilder threadInfo = new StringBuilder();
threadInfo.Append(" 线程当前的执行状态: " + thread.IsAlive);
threadInfo.Append("\n 线程当前的名字: " + thread.Name);
threadInfo.Append("\n 线程当前的优先级: " + thread.Priority);
threadInfo.Append("\n 线程当前的状态: " + thread.ThreadState);
Console.Write(threadInfo);
Console.ReadKey();
}
public static void ThreadMethod(object parameter)
{
Console.WriteLine("{0}开始执行。", Thread.CurrentThread.Name);
}
输输出结果:
2.2 线程的相关操作
2.2.1 Abort()方法
Abort()方法用来终止线程,调用此方法强制停止正在执行的线程,它会抛出一个ThreadAbortException异常从而导致目标线程的终止。下面代码演示:
```csharp
static void Main(string[] args)
{
Thread thread = new Thread(ThreadMethod); //执行的必须是无返回值的方法
thread.Name = "小A";
thread.Start();
Console.ReadKey();
}
public static void ThreadMethod(object parameter)
{
Console.WriteLine("我是:{0},我要终止了", Thread.CurrentThread.Name);
//开始终止线程
Thread.CurrentThread.Abort();
//下面的代码不会执行
for (int i = 0; i < 10; i++)
{
Console.WriteLine("我是:{0},我循环{1}次", Thread.CurrentThread