最近发现看过的东西经常记不住,想想应该定期回顾下,写写学习笔记,看来真的老了- -。
最近项目里面的兄弟们被各种并发操作,多线程操作搞的颇为狼狈,这部分的只是很有必要多多学习下(其实我个人认为还是由于一些需求策划上的不理智,自己给自己制造并发的麻烦,如果有个稍微妥协的决定,结果一定能好很多。)
线程增加了系统的健壮性和cpu的充分的利用,但是其自身的上下文切换还是有很大的开销。具体参看操作系统书籍。
CLR的一个进程内会维护一个线程池,线程池被该进程内所有应用程序域共享。线程池分为两类,一类是work thread( compute-bound operation,计算密集型线程),一类是IO thread( I/O-bound operation,IO密集型),IO密集型线程可以在不占用CPU的情况下通过设备驱动程序进行IO操作,比如带BeginXXX和endxxx方法的文件操作,网络访问等类型。
线程池大概的工作情况是这样,当开始线程池里面没有线程的情况下,当有应用程序需要线程池中线程进行工作,线程池将会新建一个线程进行工作,之后到来的请求,线程池都会尽量使用这个线程进行响应,如果请求过多的话,线程池将会创建新的线程进行响应直到达到上限。当线程池中的线程处于空闲状态一定时间后(具体多少看环境)线程池池内的空闲线程将会进行自我终结。
线程池的使用方法,最简单可以这样,当然有个重要的缺陷是我们无法知道该委托的操作什么时候完成,有没有报错。
{
Console.WriteLine("do something");
});
当然还可以使用using System.Threading.Tasks下的task类,在CLR VIA C# 3rd中对此有很详细的介绍,这也是第3版比起第2版多的部分,而且多了很多,刚刚下载,得仔细看看。
异步操作其实更多时候还是使用APM模式,也就是通过委托的BeginInvoke和endinvoke,或者是支持IO异步的各种其他方法。
错误的用法:
1、在线程池中调用thread.sleep会导致该线程池中的线程挂起,无法回到池中,当然无法分担其他任务。
2、调用beginvoke却不调用endinvoke也会使得资源无法回收。
3、注意在异步操作中的错误处理,如果不捕获会导致该所属进程崩溃。
累。。。明天继续写。。。