在异步回发期间发出并发 AJAX WCF Web 服务请求
我想在使用 AJAX 的 ASP.NET WebForms 页面上长时间运行的任务期间提供状态更新。
有没有办法让 ScriptManager 在异步回发的同时执行和处理 Web 服务请求的脚本?
我在页面上有一个发出 Web 服务请求的脚本。它在页面加载时运行并定期使用 setInterval()。它在启动异步回发之前正确运行,但在异步回发期间停止运行,并且直到异步回发完成后才再次运行。
我有一个 UpdatePanel,带有一个按钮来触发异步回发,该按钮执行长时间运行的任务。我还有一个 AJAX WCF Web 服务实例,它可以正常工作以获取数据并将其呈现在页面上,但正如我所说,直到异步回发完成之后它才会获取并呈现数据。
在异步回发期间,长时间运行的任务将更新从页面发送到 Web 服务。
问题是我可以调试并单步执行 Web 服务,并查看状态更新是否已正确设置,但在异步回发完成之前客户端脚本不会检索更新。
脚本管理器似乎正忙于执行异步回发,因此在回发完成之前它不会通过 setInterval() 运行我的其他 JavaScript。
有没有办法获取脚本管理器,或者以其他方式运行脚本以在异步回发期间从 WCF Web 服务获取数据?
我尝试了使用 PageRequestManager 在客户端 BeginRequest 事件上运行脚本以进行异步回发的各种方法,但它运行脚本,然后在页面请求执行时停止处理应通过 setInterval() 运行的代码。
I want to provide status updates during a long-running task on an ASP.NET WebForms page with AJAX.
Is there a way to get the ScriptManager to execute and process a script for a web service request concurrently with an async postback?
I have a script on the page that makes a web service request. It runs on page load and periodically using setInterval(). It's running correctly before the async postback is initiated, but it stops running during the async postback, and doesn't run again until after the async postback completes.
I have an UpdatePanel with a button to trigger an async postback, which executes the long-running task. I also have an instance of an AJAX WCF Web service that is working correctly to fetch data and present it on the page but, like I said, it doesn't fetch and present the data until after the async postback completes.
During the async postback, the long-running task sends updates from the page to the web service.
The problem is that I can debug and step through the web service and see that the status updates are correctly set, but the updates aren't retrieved by the client script until the async postback completes.
It seems the Script Manager is busy executing the async postback, so it doesn't run my other JavaScript via setInterval() until the postback completes.
Is there a way to get the Script Manager, or otherwise, to run the script to fetch data from the WCF web service during the async postback?
I've tried various methods of using the PageRequestManager to run the script on the client-side BeginRequest event for the async postback, but it runs the script, then stops processing the code that should be running via setInterval() while the page request executes.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
ajax 管道可能正在排队您的请求。
尝试使用 XHR 或 jQuery 手动进行状态调用。您可能会发现这可以解决问题。
但是...请记住,一次可以发生的并发请求数量是有限的,一旦达到限制,就会开始发生阻塞。
此限制因浏览器/版本而异。
The ajax plumbing may be queuing your requests.
Try making the status call manually with an XHR or jQuery. You may find that solves the problem.
But... keep in mind that there are a finite number of concurrent requests that can be happening at one time and that once the limit is reached blocking starts to happen.
This limit varies by browser/version.
使用 Web 开发助手进一步检查后,发现 Web 服务请求的间隔时间为 I设置(5 秒),但长时间运行的任务期间的第一个请求需要任务的持续时间才能返回结果,而后续请求将继续不返回任何内容。任务完成后,任务开始时发送的第一个 Web 服务请求将返回状态数据。
我一直试图找出为什么在任务完成之前对 Web 服务的初始请求不会返回。在 AsyncPostBack 请求结束之前,会话变量可能不会更新,因此我尝试了 ASP.NET 缓存,但这也不起作用。我在 InstanceContextMode.PerSession 和 InstanceContextMode.Single 模式下尝试使用 Web 服务使用本地变量。
我一直在遵循 MSDN Mag:2007 年 7 月的示例:前沿,但使用 ASP.NET 缓存似乎对 AsyncPostBack 没有帮助。我将尝试直接在代码隐藏中调用 WebMethod 方法,而不是 AsyncPostBack,但文章说它应该可以工作,所以我想弄清楚为什么我的实现不能。
所以:
Upon further inspection with Web Developent Helper, it appears that the web service requests are being made at the interval I set (5 secs), but the first request during the long-running task takes the duration of the task to return a result, while subsequent requests continue to return nothing. When the task completes, the first web service request sent when the task began returns with the status data.
I've been trying to figure out why the initial request to the web service doesn't return until the task completes. Session variables may not be updated until the end of the AsyncPostBack request, so I tried the ASP.NET cache, but that doesn't work either. I tried a local variable with the web service, both in InstanceContextMode.PerSession and InstanceContextMode.Single modes.
I've been following the example from MSDN Mag: July 2007: Cutting Edge, but using the ASP.NET cache doesn't seem to help with the AsyncPostBack. I'm going to try calling WebMethod methods in my code-behind directly instead of the AsyncPostBack, but the articles says it should work, so I'd like to figure out why my implementation doesn't.
So:
把它放在你的脚本管理器之后。
Throw this in after your scriptmanager.
后续为任何将来可能发现此问题的人提供解决方案。
我尝试以多种方式发送请求:
事实证明,即使客户端请求已发送(即未由 ASP.NET ScriptManager 缓冲),如果它是 IIS 中同一网站的一部分,WCF 服务也不会响应。
因此,我没有创建完全独立的 WCF 项目和完全独立的 IIS 网站,而是改用传统的 ASP.NET (SOAP) Web 服务 (.asmx)。
我能够在 Visual Studio 中保留同一项目的 .asmx 服务部分,并在 IIS 中保留网站。请求在回发期间发送,服务在回发期间响应。
将其添加为 ScriptManager 下的 ServiceReference 后,我还能够使用本质上相同的脚本对象,创建一个新的 ProgressWebService(),然后调用 ProgressWebService.GetProgress()。然后,传递给 GetProgress() 的回调处理程序会处理响应并更新 UI。
Web 服务:
客户端:
和服务器端:
A follow-up with a solution for anyone that may find this in the future.
I tried sending the request in a multitude of ways:
It turns out that even if the client request is sent, i.e., not buffered by the ASP.NET ScriptManager, that the WCF service won't respond if it is part of the same website in IIS.
So rather than creating an entirely separate WCF project, and an entirely separate IIS website, I switched to a traditional ASP.NET (SOAP) web service (.asmx).
I was able to keep the .asmx service part of the same project in Visual Studio, and website in IIS. The request is sent during a postback, and the service responds during a postback.
After adding it as a ServiceReference under the ScriptManager, I was also able to use essentially the same scripting objects, creating a new ProgressWebService(), then calling progressWebService.GetProgress(). A callback handler passed to GetProgress() then handles the response and updates the UI.
Web service:
Client side:
And the server-side: