在ASP.Net中,如何在发送页面后运行代码

时间:2010-08-25 18:43:15

标签: asp.net page-lifecycle

在ASP.Net中,我想在页面已经发送给用户后运行一些代码(日志记录,其他清理)。我不希望此代码干扰客户端接收响应所花费的时间。我尝试将此代码放在页面的OnUnload部分,但通过测试(使用断点或繁忙的等待循环),客户端实际上不显示页面,直到OnUnload中的代码完成执行。即使响应对象此时不再可用,因此我假设缓冲响应已发送到客户端,客户端仍然不显示页面,直到OnUnload完成执行。目前似乎工作的唯一方法是启动一个新线程来完成工作,并允许OnUnload立即完成。但是,我不知道这是否安全。如果在已经发送页面后执行太长时间,服务器是否会终止该线程?有没有更正确的方法来实现这一目标?

7 个答案:

答案 0 :(得分:2)

基比,

尝试重写Page.Render方法并刷新响应,如下所示:

Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
    MyBase.Render(writer)

    Response.Flush() ' Sends all buffered output to the client

    ' Run some code after user gets their content
End Sub

我认为此时响应仍然不完整,但在完成最终代码运行之前,用户将获得页面呈现的内容。

HTH,

麦克

答案 1 :(得分:1)

卸载是ASP.NET页面生命周期的最后一部分。请参阅以下链接:

http://msdn.microsoft.com/en-us/library/ms178472.aspx

这是用javascript还是AJAX做的事情?

答案 2 :(得分:0)

挂钩到page.Disposed事件而不是Unload事件怎么样?

答案 3 :(得分:0)

根据您的需要,可以创建ISAPI过滤器,以便在响应结束时执行操作。

答案 4 :(得分:0)

您可以尝试此解决方案 - Best ASP.NET Background Service Implementation

使用Windows服务并通过MSMQ与它通信可能是一个更可靠的解决方案,可以更好地扩展。这将帮助您分离关注点,让asp.net前端只关注用户,而Windows服务则专注于后台任务。

如果您使用azure迁移到云,您可以简单地用web角色替换asp.net前端,并且具有辅助角色的Windows服务和您的解决方案可以无缝扩展!

答案 5 :(得分:0)

这是一个非常简单的方法。有一个第二个aspx页面可以完成所有“清理”后渲染逻辑。例如,将其称为“cleanup.aspx”。让您的清理代码在cleanup.aspx的Page_Load中运行:

public partial class cleanup: System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e) 
    {
        // do logging blah blah here....
    }
}

在您的主aspx页面中,有一个JavaScript函数可以对'cleanup.aspx'进行AJAX调用。页面加载后激活AJAX功能。我建议使用jquery,如果是这样,你的代码将如下所示:

$(function(){
    yourAJAXYFunctionName();
});

function yourAJAXYFunctionName()() {
 // ajax code here
 //  
 $.ajax({
   url: "cleanup.aspx",
  });
}

这样,您的第一页代码就会运行,然后该页面就会被发送到浏览器。当页面呈现给客户端时,第二个ASPX页面是通过AJAX调用的,这对cleanup.aspx来说无关紧要,它不关心它的被调用及其页面加载事件是如何执行的。然后运行您的清理/日志记录代码。

警告:客户端JavaScript是必需的。但到底是谁还没有JS运行呢?另外,你的cleanup.aspx页面完全从你的主页面中抽象出来,所以如果你想使用源自你的第一页的cleanup.aspx中的任何对象,那么你必须将它们存储在会话或cookie中,或者你可以将它们作为参数传递给AJAX调用。这需要动态操作AJAX脚本本身,但这并不太难。

答案 6 :(得分:-1)

更好的我认为尝试尝试{Response.End()} catch {} runco​​de();