1、多线程基础
1.1 基本概念
- 进程:进程是操作系统中的一个基本概念,进程包含了一个程序运行所需的资源,一个进程包含多个线程。
- 线程:线程是进程的基本执行单元,进程入口执行的第一个进程称为主线程。
- 任务:任务是一个工作单元,目的是生成结果值,或产生想要的效果。任务代表需要执行的一个作业,而线程是代表这个作业的工作者。
- 线程池:多个线程的集合,决定如何处理线程分配的逻辑。
1.2 多线程的性能问题
善用多线程可以提高程序的执行效率,例如要长时间处理数据时,可以将处理工作在其他线程中执行,避免主线程出现假死状态,也可以提高程序效率。然而,上下文切换是有代价的。必须将CPU当前的内部状态保存到内存,还必须加载与新线程关联的状态。如果线程太多,切换开销也会随之增加,反而会影响程序性能。
2、System.Threading.Thread
System.Threading.Thread是用于控制线程的基础类,通过Thread可以控制当前应用程序中线程的创建、挂起、停止、销毁。
2.1 常用属性
- CurrentContext——获取线程正在其中执行的当前上下文
- CurrentThread——获取当前正在运行的线程
- ExecutionContext——获取包含有关当前线程的各种上下文信息的对象
- IsAlive——获取一个值,该值指示当前线程的执行状态
- IsBackground——获取或设置一个值,该值指示某个线程是否为后台线程
- IsThreadPoolThread——获取一个值,该值指示线程是否属于托管线程
- ManagedThreadId——获取当前托管线程的唯一标识
- Priority——获取或设置一个值,该值指示线程的调度优先级
- ThreadState——获取一个值,该值包含当前线程的状态
2.2 常用方法
- Start()——执行本线程
- Join()——阻塞调用线程,直到某个线程终止为止,可以传递int或TimeSpan参数,设置阻塞线程的事件
- Suspend()——挂起当前线程,如果当前线程已属于挂起则不起作用
- Resume()——继续运行已挂起的线程,如果线程没有挂起则引发异常
- Sleep()——将正在运行的线程挂起,挂起事件可能超过指定的时间长度
- Abort()——终止线程,尽量不要终止线程
2.3 Thread类的使用
Thread提供初始化方法有两个重载方法,分别是传递ThreadStart委托和ParameterizedThreadStart委托。两者的区别是后者可以接收参数。当调用Thread对象的Start()后,便开始异步执行委托方法。
2.4 实例
在ShowMessage()方法中输出当前线程Id,并使用Sleep()方法模拟长时间的处理工作,在主线程中创建并开始执行异步执行。
class Program
{
static void Main()
{
Console.WriteLine("Main ThreadId is : {0}", Thread.CurrentThread.ManagedThreadId);
Thread thread = new Thread(ShowMessage);
thread.Start();
Console.WriteLine("Main thread working is Complete!");
}
private static void ShowMessage()
{
Console.WriteLine("ThreadId = {0}", Thread.CurrentThread.ManagedThreadId);
for (int i = 0; i < 10; i++)
{
Thread.Sleep(100);
Console.WriteLine("The Number is {0}", i.ToString());
}
}
使用ParameterizedThreadStart委托接收参数并输出
public class Person
{
public string Name {get; set;}
public string Age {get; set;}
}
class Program
{
static