C#多线程

线程是代码的基本执行单元,多线程允许使用运行多个执行单元。

System.Threading.Thread操作线程。

主线程

才程序运行时,系统会为其创建一个线程,称作主线程。主线程从Main方法开始执行。

进程

进程包含程序运行中所有资源,包括线程。

一个进程至少包含一个线程,即主线程。

当前线程

通过Thread.CurrentThread{get;}静态属性,可以获取当前执行线程。

Console.WriteLine(Thread.CurrentThread.ManagedThreadId);

创建线程

通过Thread类,可以创建线程。

Thread类的构造函数需要一个无参或者一个参数的委托,调用对应的Start方法开始执行。

Thread t = new Thread(()=>
{
    Console.WriteLine("hello from another thread");
});
t.Start();
Console.ReadLine();

新线程和主线程同时运行,需要等待新线程完成。

前台线程和后台线程

通过IsBackbround{get;set;}属性,可以设置线程是前台还是后台。

后台线程在没有执行完毕时,主线程退出,线程也结束,程序退出。

前台线程在没有执行完毕时,即使主线程结束,线程也不退出,程序也不结束。

线程优先级

操作系统会对线程进行调度,分给线程执行时间。

优先级决定了各自分配执行时间的多少。

System.Threading.ThreadPriority枚举说明了不同的优先级。

    public enum ThreadPriority
    {
    	//最低
        Lowest = 0,
        //低于一般
        BelowNormal = 1,
        //一般优先级,默认
        Normal = 2,
        //高于一般AboveNormal = 3,
        //最高
        Highest = 4
    }

在创建线程和线程运行时,可以通过ThreadPriority属性设置线程的优先级。 一般情况下,保持默认优先级即可。

线程运行状态

通过Thread.ThreadState属性,可以获取线程状态。

未开始。创建了线程,但没有运行。

正在运行。线程正在执行。

等待。在线程上调用了Sleep等方法,线程正在休眠,系统不会调度休眠线程。

已结束。线程已经执行完毕。

挂起。线程已被暂停。

结束线程

自动结束。当线程里的代码执行完毕,线程会自动结束。

强制结束。调用Abort方法。会在调用线程上引发ThreadAbortException并最终导致线程结束。

线程可以捕获ThreadAbortException,甚至吃掉它,但线程依旧会终止,除非调用public static Thread.ResetAbort()阻止线程结束。

Thread thread = new Thread(()=>{
    while(true){
        try
        {
            Console.WriteLine("I am running");
            Thread.Sleep(1000);

        }catch(ThreadAbortException){
            Console.WriteLine("线程终止");
            //Thread.ResetAbort();//本句代码可以取消终止
        }
    }
});

thread.IsBackground = true;
thread.Start();
Console.WriteLine("按任意键终止线程");
Console.ReadLine();
thread.Abort();
Console.ReadLine();

线程异常

如果在线程中出现未处理异常,程序会终止。

ThreadAbortException例外 它负责结束线程。

线程池

线程的创建销毁需要代价,线程池维护了一组预先创建的线程,可以减少大量任务反复创建线程的开销。

System.Threading.ThreadPool操作线程池。

添加任务

ThreadPool.QueueUserWorkItem(_=>{
    Console.WriteLine("hello from thread pool");
})

线程池中的线程都是后台线程。

线程池中的任务不宜占用太多执行时间,否则可能导致没有更多线程处理任务。

多线程的作用

提高程序效率

现代CPU都是多核,多线程可以提高运行速度。

增强可用性

多线程可以将耗时任务放在后台,用户界面可以不等待。