异步刷新问题.doc

上传人:大米 文档编号:562153392 上传时间:2023-05-22 格式:DOC 页数:8 大小:150.51KB
返回 下载 相关 举报
异步刷新问题.doc_第1页
第1页 / 共8页
异步刷新问题.doc_第2页
第2页 / 共8页
异步刷新问题.doc_第3页
第3页 / 共8页
异步刷新问题.doc_第4页
第4页 / 共8页
异步刷新问题.doc_第5页
第5页 / 共8页
点击查看更多>>
资源描述

《异步刷新问题.doc》由会员分享,可在线阅读,更多相关《异步刷新问题.doc(8页珍藏版)》请在金锄头文库上搜索。

1、当心异步刷新后的脚本文件加载 重现问题 我们现在编写一个示例来重现一个异步刷信的问题。 首先,我们建立一个名为“ScriptHandler.ashx”的Generic Handler,它的作用是模拟一个脚本文件。可以看出,加载这么一个脚本文件是一个很耗时的操作。 ScriptHandler.ashx using System; using System.Web; public class ScriptHandler : IHttpHandler public void ProcessRequest (HttpContext context) context.Response.ContentTy

2、pe = text/javascript; System.Threading.Thread.Sleep(3000); context.Response.Write(Sys.Application.notifyScriptLoaded();); / . 然后我们创建一个简单的页面,放置一个UpdatePanel和两个按钮。 Page 下面的代码是响应按钮Click事件的实现。当我们点击“Load Script File”按钮时,ScriptHandler.ashx会被作为脚本文件添加到页面上。而“Partial Rendering”则会发起一个需要等待很长时间的异步刷新。 Event Handl

3、er protected void Button1_Click(object sender, EventArgs e) ScriptManager.RegisterClientScriptInclude(this.Page, this.GetType(), key, ScriptHandler.ashx?m= + new Random(DateTime.Now.Millisecond).Next(); protected void Button2_Click(object sender, EventArgs e) Thread.Sleep(5000); 您可以点击这里下载这个重现问题的示例并将

4、它部署在您的机器上,您也可以点击这里察看这个页面。请一步一步跟着我来浏览这个页面,我会示范一下这个问题。 打开页面,我们可以看到时间和两个按钮。 点击“Load Script File” 按钮,并等待时间更新。 在时间更新后,点击“Partial Rendering” 按钮。 一般来说,最后一步之后大约5秒多钟,时间将会被跟新。但是现在您会发现,直到您重新点击某个按钮之后时间才会更新。事实上最后一步的任何操作,例如脚本加载,Hidden Field的注册都失败了,客户端生命周期的事件也不会触发。原因何在? 在我分析客户端异步刷新的机制之前,我想简单的解释一些JavaScript语言和DOM操作

5、的基本特性。使用JavaScript来操作页面中的DOM是AJAX技术的基础。有人说,JavaScript编程是没有多线程的,因此我们能够认为它始终线程安全。我同意这一点。JavaScript的编程模型的确没有多线程的机制,它是线程安全的从理论上来说的确是这样。 但是,使用JavaScript进行编程还是会遇到同步问题,因为有些操作是异步得,尤其是在我们作一些DOM操作时。在AJAX编程中最著名的异步操作自然就是XMLHttpRequest对象的send方法。当我们调用了send方法之后,下面的代码并不会被阻塞,而是会继续执行下去。我们还会遇到别的异步操作。例如,开发人员经常会发现,他们无法在

6、页面中动态创建了图片()或者添加了脚本文件引用()之后立即获得图片得尺寸或者执行文件中定义的方法,这是因为下载图片和加载脚本文件都是异步操作。在大多数情况下,异步操作无法立即生效,它往往会使用一些类似于回调函数的机制来通知开发人员事情已经准备好了。 我们不难理解异步操作可能会带来同步性方面的问题。我画了一幅示意图来展示异步刷新机制中可能存在的同步和异步操作。请注意,在ASP.NET AJAX的设计中,PageRequestManager使用了标准的Singleton模式,因此在整个页面中只存在一个PRM实例。这看起来还真是一个同步问题的温床。 /P 这并不是一幅客户端生命周期的示意图。因为我要

7、指出问题是如何实现的,因此需要表现的是异步刷新过程中的一些细节。 请注意图中橙色的箭头,它代表了异步操作中的等待实现,它们是唯一可能造成同步问题的地方。过程中其余部分不会被中断,这是语言特性决定的。 图中深蓝色的三个部分导致了同步问题的发生。如果我说,这些部分的本意是为了避免问题的发生,您是否会觉得惊讶呢?让我们通过分析相关实现来看一下这三个关键步骤是如何工作的: 实现 function Sys$WebForms$PageRequestManager$_onFormSubmit(evt) / . / prepare the request object var request = new Sy

8、s.Net.WebRequest(); / . / initialize request var handler = this._get_eventHandlerList().getHandler(initializeRequest); / . / Step 1 - 1: abort the existing async postback this.abortPostBack(); / Step 1 - 3: replace the request object this._request = request; / invoke the request request.invoke(); /.

9、 function Sys$WebForms$PageRequestManager$abortPostBack() if (!this._processingRequest & this._request) this._request.get_executor().abort(); / Step 1 - 2: clear the request object this._request = null; function Sys$WebForms$PageRequestManager$_onFormSubmitCompleted(sender, eventArgs) this._processi

10、ngRequest = true; / . / Step 2: validate the request if (!this._request | sender.get_webRequest() != this._request) return; / . / execute and load scripts scriptLoader.loadScripts(0, Function.createDelegate(this, this._scriptsLoadComplete), null, null); function Sys$WebForms$PageRequestManager$_scri

11、ptsLoadComplete() /. / Page loaded this._pageLoaded(false); / Step 3 - 1: end postback this._endPostBack(null, this._response); /. function Sys$WebForms$PageRequestManager$_endPostBack(error, response) this._processingRequest = false; / Step 3 - 2: clear the request this._request = null; /. 从上面的代码中我

12、们可以发现这三个步骤都是基于当前异步刷新的Request对象进行的。当一个新的异步刷新被发起时,之前的那个异步刷新将被取消。与此同时,旧的Request对象将从PRM对象中除去,并使用新的对象来替换它(step 1)。在得到了服务器端的Response之后,我们会检验Response的Request对象是否为PRM对象上的那个。如果两个Request对象并不是同一个,则表示获得的Response对象并不是当前的Request对象所对应的那个,我们则会将其直接丢弃(step 2)。在异步刷新结束之后,PRM对象上的Request对象则会被去除(step 3)。 下面的示意图向您展示了用户连续发出两个异步请求时的状况。 这是用户在前一个异步刷新等待服务器端回应时发起第二个异步刷新的情况。那么如果一个信息的异步刷新请求在前一个正在加载脚本文件时被发起了,又会出现什么状况呢?我们可以通过下一幅示意图来观察这个状况: 第二个请求在第一次异步刷新加载脚本时发起。如果在第二次请求得到服务器端的结果之前脚本文件加载完成,则PRM对象上的Request对象就被去除了即时目前的对象并不属于第一次异步刷新。这时,当第二次异步刷

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 生活休闲 > 社会民生

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号