一个进程可以包含单个或多个线程
线程用Thread表示
任务代表需要执行的操作,用Task表示
线程池是多个线程的集合,决定如何向线程分配任务,用ThreadPool表示
一个任务开始时线程池分配线程来进行工作,工作完毕后解除分配
多线程有不确定性,C#中经常用lock语句(锁)进行处理,lock表示该部分的代码只能由一个线程进行处理,其它线程运行到此处时将被挂起,直到这部分代码被第一个线程执行完毕。但是这种操作可能会发生死锁。
例如:线程A获取了a锁,请求了b锁,被挂起,等待获取了b锁的线程B执行b锁;同时线程B请求了a锁,在线程A等待线程B时,线程B也开始等待线程A,结果是线程A和线程B同时被挂起等待对方。
线程管理的基本操作
Thread
1、Join()方法使一个线程等待另一个线程直到其终止,带上int或TimeSpan参数可以告诉线程等待时长
2、IsBackGround属性的值设置为true可将线程标记为后台线程
3、ThreadState属性表示线程状态的枚举值
4、Priority属性可设置为ThreadPriority的枚举值来确定线程的优先级
5、Sleep()方法可用毫秒数或TimeSpan作为参数确定线程至少睡眠多久,但是并不确定,因为时间过后线程不一定会被唤醒,所以Sleep()是一种不好的处理方式,不过可以用来将当前线程的时间片交给其他线程或在测试代码中模拟高延迟操作
6、Abort()方法执行时会尝试销毁线程,不保证成功,且会引发异常,但是即使异常被捕获并忽略,该方法仍会继续尝试销毁线程;lock中的关键代码无法阻止异常,执行lock代码的线程可能会因为异常中断,造成后面的线程在上个线程的lock代码执行不完全的情况下进入lock
应避免在生产代码中使用sleep()和Abort()
Task
1、Run()方法立即开始在新线程执行任务,它是Factory.StartNew()的简化形式
2、Wait()方法的作用相当于Thread的Join(),强制主线程等待任务在其他线程完成后继续运行,同一用途的方法还有WaitAll()和WaitAny()
3、IsCompleted表示任务是否结束,任务结束后,IsCompleted属性会被设置为true。
4、Result属性可以获取委托的结果,读取Result属性会自动造成线程阻塞,直到获取到Result值
5、Status属性可以获取一个TaskStatus类型的值
6、ContinueWith()可延续异步任务,延续的任务执行时是异步且无序的