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

发布于 2024-09-16 03:59:04 字数 309 浏览 4 评论 0原文

在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

云朵有点甜 2024-09-23 03:59:04

Kibbee,

尝试重写 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,

迈克

Kibbee,

Try overriding the Page.Render method and flushing the response like so:

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

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

乖乖公主 2024-09-23 03:59:04

卸载是 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?

2024-09-23 03:59:04

如何挂钩 page.Dispose 事件而不是 Unload 事件?

How about hooking into the page.Disposed event instead of the Unload event?

妄司 2024-09-23 03:59:04

根据您需要执行的操作,可以创建 ISAPI 过滤器来在响应末尾执行操作。

Depending on what you need to do an ISAPI filter can be created to do stuff at the end of the response.

§普罗旺斯的薰衣草 2024-09-23 03:59:04

您可以尝试此解决方案 - 最佳 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!

聚集的泪 2024-09-23 03:59:04

这是一个乡下人的方法。有第二个 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 脚本本身,但这并不太难。

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:

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

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:

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

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

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.

爱的十字路口 2024-09-23 03:59:04

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

Better i think try try{Response.End()}catch{} runcode();

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文