在 ASP.Net 中,如何在发送页面后运行代码
在 ASP.Net 中,我想在页面发送给用户后运行一些代码(日志记录、其他清理)。我不希望此代码干扰客户端接收响应所需的时间。我尝试将此代码放在页面的 OnUnload 部分中,但通过测试(使用断点或繁忙的等待循环),客户端实际上不会显示页面,直到 OnUnload 中的代码执行完毕。即使此时响应对象不再可用,因此我假设缓冲的响应已发送到客户端,但客户端仍然不会显示页面,直到 OnUnload 执行完毕。目前看来唯一可行的方法是启动一个新线程来完成工作,并允许 OnUnload 立即完成。不过,我不知道这是否安全。如果页面发送出去后执行时间过长,服务器会杀死该线程吗?有更正确的方法来实现这一点吗?
In ASP.Net, I want to run some code (logging, other cleanup) after the page has already been sent to the user. I don't want this code to interfere with the amount of time it takes the client to receive a response. I tried placing this code in the OnUnload part of the page, but through testing (using breakpoints, or busy waiting loops) the client does not actually display the page until the code in the OnUnload is finished executing. Even though the response object is no longer available at this point, and therefore I would assume that the buffered response has been sent to the client, the client still does not display the page until the OnUnload is finished executing. The only way that seems to work at the moment is to start a new thread to do the work, and allow the OnUnload to finish immediately. However, I don't know if this is safe or not. Will the server kill the thread if it executes too long after the page is already sent out? Is there a more correct way to accomplish this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
Kibbee,
尝试重写 Page.Render 方法并像这样刷新响应:
我认为此时响应仍然不完整,但用户将在完成运行最终代码之前获得页面呈现的内容。
HTH,
迈克
Kibbee,
Try overriding the Page.Render method and flushing the response like so:
I think at this point the response still isn't complete, but the user will get what the page has rendered before you finish running that final code.
HTH,
Mike
卸载是 ASP.NET 页面生命周期的最后一部分。请参阅下面的链接:
http://msdn.microsoft.com/en-us/ Library/ms178472.aspx
这是你可以用 javascript 或 AJAX 做的事情吗?
Unload is the last part of the ASP.NET page life cycle. See link below:
http://msdn.microsoft.com/en-us/library/ms178472.aspx
Is this something you could do with javascript or AJAX?
如何挂钩 page.Dispose 事件而不是 Unload 事件?
How about hooking into the page.Disposed event instead of the Unload event?
根据您需要执行的操作,可以创建 ISAPI 过滤器来在响应末尾执行操作。
Depending on what you need to do an ISAPI filter can be created to do stuff at the end of the response.
您可以尝试此解决方案 - 最佳 ASP.NET 后台服务实现
使用 Windows服务并通过 MSMQ 与之通信可能是一个更可靠的解决方案,并且可以更好地扩展。这将帮助您分离关注点,让 ASP.NET 前端只关注用户,而 Windows 服务专注于后台任务。
如果您要使用 azure 迁移到云,您只需将 ASP.NET 前端替换为 Web 角色,将 Windows 服务替换为辅助角色,您的解决方案就可以无缝扩展!
You could try this solution - Best ASP.NET Background Service Implementation
Using a windows service and communicating with it through MSMQ might be a far more reliable solution and can scale up better. This will help you separate the concerns and let asp.net front end just focus on the user while the windows service focusses on the background tasks.
If you are moving to the cloud with azure, you can simply replace the asp.net front end with a web role and the windows service with a worker role and ur solution can scale seamlessly!
这是一个乡下人的方法。有第二个 aspx 页面来完成所有“清理”后渲染逻辑。例如,将其称为“cleanup.aspx”。让清理代码在 cleanup.aspx 的 Page_Load 中运行:
在主 aspx 页面中,有一个 JavaScript 函数对“cleanup.aspx”进行 AJAX 调用。使 AJAX 函数在页面加载后触发。我推荐 jquery,如果是这样,您的代码将如下所示:
这样,您的第一个页面的代码将运行,然后该页面将发送到浏览器。当页面呈现给客户端时,第二个 ASPX 页面通过 AJAX 调用,这对于 cleanup.aspx 来说并不重要,它不关心它是如何调用的以及它的页面加载事件是如何执行的。然后运行您的清理/日志记录代码。
注意事项:需要客户端 JavaScript。但到底谁没有运行 JS 呢?另外,你的 cleanup.aspx 页面完全是从你的主页中抽象出来的,所以如果你想使用 cleanup.aspx 中源自你的第一页的任何对象,那么你必须将它们存储在会话或 cookie 中,或者你可以将它们作为 AJAX 调用中的参数传递。这需要动态操作 AJAX 脚本本身,但这并不太难。
Here's a redneck way to do it. Have a second aspx page that does all your "clean up" post-rendering logic. Call that one 'cleanup.aspx' for example. Have your clean up code run in Page_Load of cleanup.aspx:
In your main aspx page, have a JavaScript function that makes an AJAX call to 'cleanup.aspx'. Make the AJAX function fire after page load. I recommend jquery, if so your code will look like this:
This way, your first page's code runs, then the page is sent to the browser. As the page renders to the client, the 2nd ASPX page is called via AJAX, which really doesn't matter to cleanup.aspx, it doesn't care how its called and its page load event is executed. Your cleanup/logging code is then ran.
Caveats: client side JavaScript is required. But really who the hell doesn't have JS running anyway? Also, your cleanup.aspx page is totally abstracted from your main page, so if you want to use any object in cleanup.aspx that originated in your first page, then you'll have to store them in session or cookies, or you can pass them as parameters in the AJAX call. That will require dynamic manipulation of the AJAX script itself, but that's not too hard.
我认为更好的是尝试 try{Response.End()}catch{} runcode();
Better i think try try{Response.End()}catch{} runcode();