В ASP.Net я хочу запустить некоторый код (ведение журнала, прочая очистка) после того, как страница уже была отправлена пользователю. Я не хочу, чтобы этот код влиял на количество времени, необходимое клиенту для получения ответа. Я попытался разместить этот код в части страницы OnUnload, но при тестировании (с использованием точек останова или циклов ожидания) клиент фактически не отображает страницу до тех пор, пока код в OnUnload не завершит выполнение. Несмотря на то, что на данный момент объект ответа больше не доступен, и поэтому я предполагаю, что буферизованный ответ был отправлен клиенту, клиент по-прежнему не отображает страницу до тех пор, пока выполнение OnUnload не завершится. Единственный способ, который кажется работающим на данный момент, - это запустить новый поток для выполнения работы и позволить OnUnload немедленно завершиться. Однако я не знаю, безопасно это или нет. Будет ли сервер убивать поток, если он выполняется слишком долго после того, как страница уже отправлена? Есть ли более правильный способ сделать это?
В ASP.Net, как запустить код после отправки страницы
Ответы (7)
Кибби,
Попробуйте переопределить метод 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,
Майк
Выгрузка - это последняя часть жизненного цикла страницы ASP.NET. См. Ссылку ниже:
http://msdn.microsoft.com/en-us/library/ms178472.aspx
Можно ли это сделать с помощью javascript или AJAX?
Как насчет подключения к событию page.Disposed вместо события Unload?
В зависимости от того, что вам нужно сделать, может быть создан фильтр ISAPI, чтобы делать что-то в конце ответа.
Вы можете попробовать это решение - Лучшая реализация фоновой службы ASP.NET
Использование службы Windows и взаимодействие с ней через MSMQ может быть гораздо более надежным решением и лучше масштабируется. Это поможет вам разделить проблемы и позволить интерфейсу asp.net просто сосредоточиться на пользователе, в то время как служба Windows сосредоточится на фоновых задачах.
Если вы переходите в облако с помощью Azure, вы можете просто заменить интерфейс asp.net на веб-роль, а службу Windows на рабочую роль, и решение ur можно легко масштабировать!
Вот способ сделать это деревенщиной. Имейте вторую страницу aspx, которая выполняет всю вашу логику «очистки» пост-рендеринга. Назовите его, например, «cleanup.aspx». Запустите код очистки в Page_Load файла cleanup.aspx:
public partial class cleanup: System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// do logging blah blah here....
}
}
На главной странице aspx имейте функцию JavaScript, которая выполняет вызов AJAX для cleanup.aspx. Включите функцию 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, но это не слишком сложно.
Лучше я думаю попробуйте попробовать {Response.End ()} catch {} runcode ();