看这里: http://msdn.microsoft.com/en-us/magazine/cc163725.aspx
ASP.NET2.0 异步页面技术是用来解决页面执行长时间,复杂逻辑代码所造成的页面长时间不呈现。它与我们平常说Ajax技术有着很大区别。
ASP.NET2.0异步技术采用.Net framework的多线程技术来解决的。当我们在ASP.NET页面中标记Async='True'时,页面编译器将会自动编译成异步类并实现IHttpasynchandler. 同时ASPNET_ISAPI会将请求带入异步管道进行实际的页面执行。
此时我们发现在Page_PreRender事件之后,PreRenderComplete事件之前,它启动了一个后台线程来执行相应的任务。为什么会选择在这个事件时候发生,并且后台线程怎么找到并返回结果的呢?那是因为有个叫做Async point “异步点”的东西来决定的。
但是当我们要同时处理多个异步任务,我们怎么做呢?通常
但是,当我们启动Trace 的时候我们会发现:
启动了2个线程,异步页面只有所有的请求返回。也就意味着如果我们写N个异步调用就启动N个异步线程,并且如果任何其中一个卡死,那页面就会block掉直到超时.
当然那样是不好的,其实面对这样的问题,我们都需要自定义IAsyncResult.在内部,我们可以控制是否所有的任务都完成才返回,具体实现请下载代码查看(CompositeAsyncResult.cs)
当我们再执行下列代码时,会发现始终只启动了一个线程。
同时,我要提一下PageAsyncTask方法:
看看MSDN上的解释,我们就会发现,它是独立Asynchronous 页面的。就算你将页面的Async=‘false’,它一样的实行异步任务,只是将会阻塞页面线程。
ASP.NET 版本 2.0 允许您注册多个任务到页,并在呈现页之前异步运行这些任务。如果任务进程缓慢,且您不希望在执行它时拖延其他进程,则您可指定异步运行该任务。异步任务可并行或顺序执行。
PageAsyncTask 对象必须通过 RegisterAsyncTask 方法注册到页。页本身无需异步处理以执行异步任务。您可在页指令上将 Async 属性设置为 true(如下面的代码示例所示)或 false,异步任务将仍然异步处理:
<%@ Page Async="true" %>
当 Async 属性设置为 false 时,在所有异步任务完成之前,执行页的线程将被阻止。
任何在 PreRenderComplete 事件之前注册的异步任务如果还未执行,则将由页自动执行。在 PreRenderComplete 事件之后注册的异步任务必须通过 ExecuteRegisteredAsyncTasks 方法显式执行。ExecuteRegisteredAsyncTasks 方法也可用于在 PreRenderComplete 事件之前启动任务。ExecuteRegisteredAsyncTasks 方法执行页上所有未执行的注册异步任务。
默认情况下,如果异步任务未在 45 秒钟内完成,则它将超时。您可在 Web.config 文件或页指令中指定不同的超时值。Web.config 文件的 <pages> 节包含 asyncTimeout 属性,如下所示。
<system.web>
<pages asyncTimeout="30">
</pages>
</system.web>
页指令包含 AsyncTimeout 属性。
<%@ Page AsyncTimeout="30" %>
同样的功能,更简洁的代码:
了解更多关于PageAsyncTask,点击:http://msdn.microsoft.com/zh-cn/library/system.web.ui.pageasynctask(VS.80).aspx
到了这里,我们会有些疑问,到底用哪个方法(AddOnPreRenderCompleteAsync还是RegisterAsyncTask)适合呢?他们有什么区别呢?
相同点: 从功能上讲,他们是相同的,页面请求的执行都分为2个阶段,在异步点(Async point)之前和之后.
不同点:
1. RegisterAsyncTask 是被设计用来运行页面类的异步任务的API。不仅仅是异步页面。AddOnPreRenderCompleteAsync 是专门用来执行异步页面的API。
2. One is that RegisterAsyncTask executes the End handler on a thread with a richer context than AddOnPreRenderCcompleteAsync. The thread context includes impersonation and Httpcontext information that is missing in the thread serving the End handler of a classic asynchronous page. In addition, RegisterAsyncAsyncTask allow you to set a timeout to ensure that any task doesn't run for more than a given number of seconds.
The other difference is that RegisterAsyncTask makes the implementation of multiple calls to remote sources significantly easier. You can have parallel execution by simply setting a Boolean flag, and you don't need to create and manage your own IAsyncResult object.
The bottom line is that you can use either approach for a single task, but you should opt for RegisterAsyncTask when you have multiple task to execute simultancely.