C#中线程的一些认识
TreadPool 与Asp.net
ThreadPool,是全局的一个asp.net进程w3wp.exe中只创建一个ThreadPool,asp.net 页面(.aspx)的每次请求处理会使用ThreadPool中的一个线程,可以通过System.Threading.ThreadPool.GetAvailableThreads 查看到占用情况:
具体做法是在当前站点中添加 Webservice, ws加入一个有Sleep(5000)的方法,多次调用后将TreadPool的可以线程数打印出来,可以发现变化.在HttpRuntime中ProcessRequest方法中可以看到对ThreadPool的调用印证了上面的结果. 由于上面的原因,需要慎重考虑在asp.net环境中使用ThreadPool.
SmartThreadPool
开发中需要引入线程池时,可以考虑使用 Smart Thread Pool.
关于lock(obj){}
字面上看是"锁定obj",看了不少资料说是,将obj锁定不允许其他对象(线程访问), 这个可能由于理解或表达上的错误,造成误解
实际上经过测试,在obj被"锁定"其间其他对象(或线程序)照样可以访问或修改obj的方法或属性等.
正确的理解是,lock(obj){}--L1实际上对实体obj做了一个标记, 另外的线程运行的代码段中如果也有被lock(obj){}--L2限制的代码段(不一定是同一段代码) 只要obj对应内存中同一个实体,那么这两段代码将被同步, 即L1的lock首先给obj做了"锁定标记",L2企图标记(锁定)obj时,发现对象已经被锁定,于是他只能L1腿出--即将obj的锁定标记清除.
Asp.net中使用Thread
一般将页面(html)生成,数据清理这些任务放到独立的Thread中去, 为了能访问工作进度,需要将相关任务封装到工作类中,
然后将工作类引用给Application, 在客户端通以ajax方式轮询问工作进度,如果是全局性的任务,如清理数据库脏数据,可以将工作类设计成单实例,这样就不需要将引用放在Application中了,Thread环境中不要访问Request,Response,Server.MapPath等HttpContext,他们多为null,因为.aspx页面线程多数情况下会先于工作线程(指定在创建Thread中运行的任务)结束,也不应该将http环境实体类的引用给工作类,多数情况下你应该让这些实体尽早销毁以便释放资源.
可以在启动线程前将需要用到的Http环境数据,指派给"工作类"的属性. 在asp.net环境下的Thread,可以使用httpRunting来访问相关
WebServices中的*Async签名调用
.net2.0中的WebServices代理类会生成*Async签名的方法,这个调用使用的是IO异步方法,CRL将调用给Windows系统,而Windows系统在完成工作后,在CRL进程中ThreadPool的IO线程中找到一条线程来执行回调任务,而在Windows通知CRL前工作进程(.net程序),不需要花"精力"在这个工作上.
参考:
http://www.cnblogs.com/JeffreyZhao/archive/2008/02/24/use-async-operation-properly.html