c#异步编程基础
线程(Thread)
什么是线程Thread
- 线程是一个可执行路径,它可以独立于其他线程执行.
- 每个线程都在操作系统的进程(Process)内执行,而操作系统进程提供了程序运行的独立环境.
- 单线程应用,在进程的独立环境里只跑一个线程,所以该线程拥有独占权.
- 多线程应用,在单个进程中会跑多个线程,他们会共享当前的执行环境(尤其是内存)
线程的一些属性:
- 线程一旦开始执行,IsAlive就是True,线程结束就变成false.
- 线程结束的条件:线程构造函数传入的委托结束了执行.
- 线程一旦结束,就无法重启.
- 每个线程都有个Name属性,通常用于调试.线程Name只能设置一次,以后更改会抛出异常.
- 静态的Tread.CurrentThread属性,会返回当前执行的线程.
线程的Join and Sleep
- 调用Join方法,就可以等待另一个线程结束.
- 调用Join的时候,可以设置一个超时,用毫秒或者TimeSpan都可以.
- 返回一个bool类型,如果返回true,那就是线程结束;如果返回false,那就表示超时了.
- 调用Sleep方法会暂停当前的线程,并等待一段时间.
注意:
-
- Thread.Sleep(0)这样调用会导致线程立即放弃当前的时间片,自动将CPU移交给其他的线程.
- Thread.Yield()做同样的事情,但是它只会把执行交给同一处理器上的其他线程.
- 当等待Sleep或Join的时候,线程处于阻塞的状态.
线程的阻塞
- 如果线程的执行由于某种原因导致暂停,那么就认为该线程被阻塞了.例如在Sleep或通过Join等待其他线程结束.
- 被阻塞的线程会立即将处理器的时间片生成给其他线程,从此就不再消耗处理器时间,直到满足其阻塞条件为止(然后cpu的时间片会返回到本线程).
- 可以通过ThreadState这个属性来判断线程是否处于被阻塞的状态.
bool blocked=(someThread.ThreadState & ThreadState.WaitSleepJoin)!=0;
ThreadState
- ThreadState是一个flags enum,通过按位的形式,可以合并数据的选项.
- 下图是Thread有可能处于的状态.但是它大部分的枚举值都没有什么用.四个最有用的值:Unstarted,Running,WaitSleepJoin和Stopped.

解除阻塞Unblocking
- 当遇到下列四种情况的时候,就会解除阻塞:
- 阻塞条件被满足
- 操作超时(如果设置超时的话)
- 通过Thread.Interrupt()进行打断
- 通过Thread.Abort()进行中止
上下文切换
- 当线程阻塞或解除阻塞时,操作系统将执行上下文切换.这会产生少量开销,通常为1或2微秒.
I/O-bound vs Compute-bound(或CPU-Bound)
- 一个花费大部分时间等待某事发生的操作称为I/O-bound
- I/O绑定操作通常涉及输入或输出,但这不是硬性要求:Thread.Sleep()也被视为I/O-bound
- 相反,一个花费大部分时间执行CPU密集型工作的操作称为Compute-bound
阻塞 vs 忙等待(自旋)
Blocking vs Spinning
- I/O-bound操作的工作方式有两种:
- 在当前线程上同步的等待
- Console.Readline(),Thread.Sleep(),Thread.Join()...
- 异步的操作,在稍后操作完成时触发一个回调动作.
- 在当前线程上同步的等待
- 同步等待的I/O-bound操作将大部分时间花在阻塞线程上.
- 他们也可以周期性的在一个循环里进行"打转(自旋)"
while(DateTime.Now<nextStartTime) Thread.Sleep(100);
while(DateTime.Now<nextStartTime)
- 在忙等待和阻塞方面有一些细微的差别
- 首先,如果你希望条件很快得到满足(可能在几微秒之内),则短暂的自旋可能会很有效,因为它避免了上下文切换的开销和延迟.
- .NET Framework提供了特殊的方法和类来提供帮助SpinLock和SpinWait
- 其次,阻塞也不是零成本.这是因为每个线程在生存期间会占用大约1MB的内存,并会给CLR和操作系统带来持续的管理开销.
- 因此,在需要处理成百上千个并发操作的大量I/O-bound程序的上下文中,阻塞可能会很麻烦
- 所以,此类程序需要使用基于回调的方法,在等待时完全撤销其线程
- 首先,如果你希望条件很快得到满足(可能在几微秒之内),则短暂的自旋可能会很有效,因为它避免了上下文切换的开销和延迟.

浙公网安备 33010602011771号