2010-10-15 2 views
0

У меня есть собственный класс сеансов на основе SQL. Я хочу автоматически зафиксировать данные в сеансе в конце выполнения программы (т. Е. В конце обслуживания запроса страницы). Разве деструкторы объектов (финализаторы) не выполняются в конце каждого запроса? Есть ли способ сделать это вместо того, чтобы явным образом вызывать метод Dispose() каждый раз, когда я закончил свой объект сеанса?Код должен запускаться автоматически, когда запрос завершен?

ответ

0

В C# финализаторы не являются детерминированными, что означает, что у вас нет гарантии, когда он будет выполнен. Таким образом, нет, вы не можете использовать их для своего сценария.

Я вижу два пути подойти к этому:

  1. Программным призывающих Dispose в какой-то момент к концу данной страницы life cycle (или через global.asax, как указано Майкл Г.).
  2. Попросите свой класс сеансов на основе 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 
     } 
    } 
} 

Сообщите мне, если это еще не ясно.

+0

Я пытаюсь уйти от (1). Я не хочу вспоминать, чтобы сделать фиксацию в конце каждого запроса. Кроме того, я не совсем уверен, что вы подразумеваете под (2). –

+0

Это намного яснее и прекрасно работает для меня. Благодарю. –

0

Я предлагаю пойти с поставщиком контейнеров IOC для такого рода вещей. Вы можете подключить их к концу запроса и выполнить некоторый код, особенно хорошо для некоторых транзакционных материалов.

Я использовал Autofac, у него есть метод OnActivated(), который я использую для привязки транзакции к активации сеанса.

1

Одна из возможных возможностей - использование global.asax. Существует обработчик в конце запроса, в C# вызов внутри Global.asax.cs будет выглядеть список что-то это:

protected void Application_EndRequest(object sender, EventArgs e){ 
    //perform action - you have access to the HttpContext 
} 

Вы должны следить за то, что происходит через обработчик, хотя - в зависимости от ваша конфигурация ваших активов (таблица стилей, изображений и т. д.) также может поражать этот запрос, поэтому вам, возможно, придется разработать способ обеспечения только того, чтобы на ваших страницах были предприняты действия.

+0

Я пробовал это, и объект публичного сеанса, который я создаю в global.asax, кажется, не доступен ни с каким другим объектом в приложении. –

0

Если вы отправляете явный маршрут Dispose(), ваш собственный класс сеансов SQL должен будет реализовать IDisposable.

Я также предлагаю Russell McClure's answer относительно событий.