在请求一个普通的耗时Asp.net Web页面时(比较慢的数据库查询,请求一个网络资源等),asp.net从自身维护的线程池里取出一个可用的线程处理Web页(包括对象的实例化,相应的事件处理,HTML的呈现等),当线程池里没有可用的线程时(站点的请求频率很高,线程池里的线程都在处理请求)新的请求将压入一个队列,如果队列满了,asp.net则返回"服务器不可用"的503错误以拒绝新的请求.
线程池里的线程数及队列的大小受多个因素影响,包括IIS版本,.net framework版本,机器CPU数量等
在等待较慢的数据库查询或者请求一个网络资源返回结果时,当前使用的线程被挂起,这些线程没有处理其它的逻辑也没有占用CPU,但严重影响了整个网站的吞吐量,因为站点本应该处理更多的请求的.
在这种情况下可以使用asp.net异步页提高站点的吞吐量,通过asp.net异步页可以将耗时的处理代码转移到非asp.net线程里,当异步结果返回时会通知asp.net并从Asp.net线程池里取出一个可用的线程处理结束代码并呈现HTML.


在使用asp.net异步页时有几个地方需要注意:
1.异步线程的使用
尽量使用framework内建的异步支持,SqlCommand,HttpWebRequest,FileStream等对象都提供了相关的BeginXX()和EndXX()方法,这些对象的异步方法使用的都不是Asp.net线程池里的线程.
使用delegate的BeginInvoke()或者ThreadPool.QueueUserWorkItem()都是从asp.net线程池里取可以的线程,使用它们对解决问题没有什么意义.通过Tread类创建自定义的处理线程如果不能很好的管理创建出来的线程就比较危险了(如果同时有N个请求,就会有N个线程被创建,过多的创建线程会影响Asp.net的性能并且可能导致Asp.net站点不能正常处理请求).
2.异步页并不比普通页快
因为异步页会有线程切换的过程,所以异步页并不比普通页快.当然在Asp.net异步页里可以通过RegisterAsycTask()方法执行多个并发任务.
3.错误处理
使用异步页时一定要处理好异常,如果处理不好可能会让整个进程中指,在异步操作中发生的异常会在调用EndXX()方法时抛出.
如果异常发生在返回IAsyncResult对象之前发生,可以返回一个实现了IAsyncResult接口的自定义对象.
比如在调用SqlCommand类的BeginExecuteNonQuery(AsyncCallback callback, object stateObject)方法前执行
SqlConnection.Open()方法时发生异常,因为打开数据库连接时异步操作还没有开始,所以这里的异常不会在
调用EndExecuteReader(IAsyncResult asyncResult)方法时抛出,因此需要在捕捉到打开数据库连接的异常时返回一个自定义IAsyncResult对象.

posted on 2011-04-08 22:12  空空儿  阅读(650)  评论(0编辑  收藏  举报