学习这件工作是一个习惯,不能停。。。此外这篇已经看过两个月过去,但感受有些工作不总结跟没做没啥区别,遂记下此文
1.CLR线程池根本
2.ThreadPool的简单使用操练
3.执行上下文
4.协作式打消和超时,System.Threading.CancellationTokenSource的简单使用
5.任务
6.任务调理器
一、CLR线程池根本
如26章所述,创建和销毁线程是一个昂贵的操纵,要耗费大量的时间。此外太多的线程会浪费内存资源。由于操纵系统必需调理可运行的线程并执行上下文切换,所以太多的线程还对性能倒霉。
为了改进这个情况,CLR包罗了代码打点它本身的线程池(thread pool),线程池是你的应用措施能使用的线程的调集。
每CLR一个线程池,这个线程池由CLR控制的所有AppDomain共享。
CLR初始化时,线程池中是没有线程的。在内部,线程池维护了一个操纵请求行列队伍。应用措施执行一个异步操纵时,就挪用某个要领,将一个记录项(entry)追加到线程池的行列队伍中,线程池的代码从这个行列队伍中提取记录项,将这个记录项派发(dispatch)给一个线程池线程。如果线程池中没有线程,就创建一个新线程。
如果应用措施向线程池发出许多请求,线程池会测验考试只用一个线程来处事所有请求。然而,如果你的应用措施发出请求的速度赶过了线程池线程措置惩罚惩罚它们的速度,就会创建特别的线程。
当一个线程池线程闲着没事一段时间之后,线程会本身醒来终止本身以释放资源。
二、ThreadPool的简单使用操练
class Program { static void Main(string[] args) { Console.WriteLine($"Main Thread,当前线程:{Thread.CurrentThread.ManagedThreadId}"); ThreadPool.QueueUserWorkItem(Calculate,5); Console.WriteLine($"Main Thread doing other work,当前线程:{Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(1000); Console.WriteLine("hi <Enter> to end this program~~"); Console.Read(); } //这个要领的签名必需匹配waitcallback委托 public static void Calculate(object state) { //这个要领由一个线程池线程执行 Console.WriteLine($"In Calculate:state={state},当前线程:{Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(1000); //这个要领返回后,线程回到池中,期待另一个任务 } }
View Code运行功效:
有时上图标注这两行输出功效挨次会倒置,这是因为两个要领彼此之间是异步运行的,windows调理器决定先调理哪一个线程。
三、执行上下文
每个线程都关联一个执行上下文数据布局。
执行上下文(execution context)包孕的对象有安适设置(压缩栈、Thread的Principal属性和Windows的身份)、宿主设置(System.Threading.HostExecutionContextManager)以及逻辑挪用上下文数据(参见System.Runtime.Remoting.Messaging.CallContext的LogicalSetData和LogicalGetData要领)。
默认情况下,CLR自动造成初始线程的执行上下文“流向”任何帮助线程。这造成将上下文信息传给帮助线程,但这会对性能造成必然影响。
这是因为执行上下文中包罗大量信息,而收集所有这些信息,再把它们复制到帮助线程,要耗费不少时间。
System.Threading.ExecutionContext类,允许你控制线程的执行上下文如何从一个线程“流向”另一个。可用这个类 阻止上下文流动以提升应用措施的性能。
class Program { static void Main(string[] args) { //将一些数据放到Main线程的逻辑挪用上下文中 CallContext.LogicalSetData("Name", "Michael"); //初始化要由线程池线程做的一些事情 //线程池线程能访谒逻辑挪用上下文布局 ThreadPool.QueueUserWorkItem( state => Console.WriteLine($"Name={CallContext.LogicalGetData("Name")}")); //阻止Main线程的执行上下文的流动 ExecutionContext.SuppressFlow(); //初始化要由线程池做的事情 //线程池线程不能访谒逻辑挪用上下文数据 ThreadPool.QueueUserWorkItem( state => Console.WriteLine($"Name={CallContext.LogicalGetData("Name")}")); //恢复Main线程的执行上下文的流动, //以免将来使用更多的线程池线程 ExecutionContext.RestoreFlow(); Console.ReadLine(); } }
View Code编译后运行功效如下:
四、协作式打消和超时,System.Threading.CancellationTokenSource的简单使用
Microsoft.NET Framework供给了标准的打消操纵模式。这个模式是协作式的,意味着要打消的操纵必需显式撑持打消。
CancellationToken实例是轻量级值类型,包罗单个私有字段,即对其CancellationTokenSource东西的引用。
在计算限制操纵的循环中,可按时挪用CancellationToken的IsCancellationRequsted属性,了解循环是否应该提前终止,从而终止计算限制的操纵。
提前终止的好处在于,CPU不需要再把时间浪费在你对功效不感兴趣的操纵上。