ASP.NET 2.0
的异步页面刷新功能真得很酷,今天尝试用它解决我的一个应用问题,真是帮了大忙了。
我的页面要向后台的
socket
服务提交一个查询,首先这是一个可能长时间不返回的操作;其次为了拿到
socket
服务返回的长度不定、有可能很大的
Response
数据,我不得不采用了
dotNET
的
IAsyncResult
BeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback, object state);
办法来异步提交
socket
命令,然后在回调函数中迭代调用
int
EndReceive(IAsyncResult asyncResult);
来获取
Response
数据直到数据被取完,这一系列的数据片断都缓存在一个
MemoryBlock
链表中。
这种情况下,
ASP.NET
页面要想用表格展示
Response
数据,必须能够被异步刷新。
但
ASP.NET 2.0
极大地简化了生成异步页的方式。首先使用该页的
@ Page
指令引入
Async=“true”
属性。
其次,在
Page_Load
时,注册事件
Page_PreRender
:
private void Page_Load(object sender, System.EventArgs e)
{
if (!IsPostBack)
{
//
注册事件
Page_PreRender
执行完成时执行方法
// Hook PreRenderComplete event for data binding
this.PreRenderComplete += new EventHandler(Page_PreRenderComplete);
接下来,我在点击按钮的事件函数中,开始我的异步操作之旅:
///
PageAsyncTask
的方式则是增强版本,除了异步页面处理开始和结束方法自身外,
///
还可以提供在超时情况下的处理方法,以及处理时的状态对象。
///
PageAsyncTask
task = new PageAsyncTask(
new BeginEventHandler(BeginSubmitKeywordsAsyncOperation),
new EndEventHandler(EndSubmitKeywordsAsyncOperation),
new EndEventHandler(TimeoutSubmitKeywordsAsyncOperation),
null
);
RegisterAsyncTask(task);
///
对大多数简单的异步处理情况,可以直接调用
AddOnPreRenderCompleteAsync
方法,
///
提交页面请求开始和结束时的处理代码
//AddOnPreRenderCompleteAsync(
// new BeginEventHandler(BeginSubmitKeywordsAsyncOperation),
// new EndEventHandler(EndSubmitKeywordsAsyncOperation)
//);
该页经历其常规处理生命周期,直到
PreRender
事件刚刚引发之后。然后,
ASP.NET
调用使用
RegisterAsyncTask
注册的
Begin
方法
BeginSubmitKeywordsAsyncOperation
。这个方法中我将向
sokcet
服务提交我的命令,然后将
socket.BeginReceive
方法得到的
IasyncResult
对象返回给
ASP.NET
。
然后,我的
socket
异步回调函数在最终全部获得数据流后,通过调用
callback.Invoke(result);
来通知页面
socket
这边已经完成工作了。
于是
ASP.NET
唤起
EndSubmitKeywordsAsyncOperation
方法:
///<summary>
///
异步调用结束后的接收方法
(
异步操作执行完成后
,
会重新从线程池中取个线程为本页面请求服务
).
///</summary>
///<param name="ar"></param>
void EndSubmitKeywordsAsyncOperation(IAsyncResult ar)
{
_resultDataset = _submit.getResultDataset(ar);
在这个函数中,我就可以拿到数据流了。
之后,
ASP.NET
又唤起
Page_PreRender
事件,从而可以在这个事件中,把页面上的表格正确填充了。
这样,就达到了我的目的。而且向后台提交后等待被再度激活超时了,也可以由
void
TimeoutSubmitKeywordsAsyncOperation(IAsyncResult ar)
来做合适的处理。