У меня есть собственный класс сеансов на основе SQL. Я хочу автоматически зафиксировать данные в сеансе в конце выполнения программы (т. Е. В конце обслуживания запроса страницы). Разве деструкторы объектов (финализаторы) не выполняются в конце каждого запроса? Есть ли способ сделать это вместо того, чтобы явным образом вызывать метод Dispose()
каждый раз, когда я закончил свой объект сеанса?Код должен запускаться автоматически, когда запрос завершен?
ответ
В C# финализаторы не являются детерминированными, что означает, что у вас нет гарантии, когда он будет выполнен. Таким образом, нет, вы не можете использовать их для своего сценария.
Я вижу два пути подойти к этому:
- Программным призывающих Dispose в какой-то момент к концу данной страницы life cycle (или через global.asax, как указано Майкл Г.).
- Попросите свой класс сеансов на основе SQL подключиться к событию страницы (например, событие Unload), чтобы выполнять любые действия, которые он хочет очистить.
UPDATE:
В ответ на ваш вопрос о внушении # 2, я изложим немного. Этот параметр должен каким-то образом позволить вашему классу сеансов на основе SQL получить ссылку на экземпляр веб-страницы. Один из вариантов (который я покажу ниже) должен был бы использовать конструктор класса сеанса на основе SQL для получения ссылки на веб-страницу. Тогда класс сессии на основе SQL может зарегистрироваться для любого события, которое он желает, чтобы узнать, что происходит со страницей.
namespace SomeNamespace
{
using System.Web.UI;
public class SqlBasedSession
{
public SqlBasedSession(Page webPage)
{
webPage.Unload += new EventHandler(webPage_Unload);
}
void webPage_Unload(object sender, EventArgs e)
{
// the web page is being unloaded so this class can
// cleanup it's resources now
}
}
}
Сообщите мне, если это еще не ясно.
Я предлагаю пойти с поставщиком контейнеров IOC для такого рода вещей. Вы можете подключить их к концу запроса и выполнить некоторый код, особенно хорошо для некоторых транзакционных материалов.
Я использовал Autofac, у него есть метод OnActivated(), который я использую для привязки транзакции к активации сеанса.
Одна из возможных возможностей - использование global.asax. Существует обработчик в конце запроса, в C# вызов внутри Global.asax.cs будет выглядеть список что-то это:
protected void Application_EndRequest(object sender, EventArgs e){
//perform action - you have access to the HttpContext
}
Вы должны следить за то, что происходит через обработчик, хотя - в зависимости от ваша конфигурация ваших активов (таблица стилей, изображений и т. д.) также может поражать этот запрос, поэтому вам, возможно, придется разработать способ обеспечения только того, чтобы на ваших страницах были предприняты действия.
Я пробовал это, и объект публичного сеанса, который я создаю в global.asax, кажется, не доступен ни с каким другим объектом в приложении. –
Если вы отправляете явный маршрут Dispose(), ваш собственный класс сеансов SQL должен будет реализовать IDisposable.
Я также предлагаю Russell McClure's answer относительно событий.
Я пытаюсь уйти от (1). Я не хочу вспоминать, чтобы сделать фиксацию в конце каждого запроса. Кроме того, я не совсем уверен, что вы подразумеваете под (2). –
Это намного яснее и прекрасно работает для меня. Благодарю. –