Как мне сохранить объект между потоками без использования httpcontext.items? - PullRequest
0 голосов
/ 08 апреля 2009

У меня есть объект, который обрабатывает кэширование памяти для моего уровня доступа к данным (DAL), и мне нужно сохранить его между потоками. Из того, что я прочитал, предпочтительным методом является использование httpcontext.item с кодом, подобным следующему:

   Shared Property DALList() As Dictionary(Of String, DAL)
        Get
            If Not Web.HttpContext.Current.Items.Contains("_DALList") Then
                Web.HttpContext.Current.Items.Add("_DALList", New Dictionary(Of String, DAL))
            End If
            Return Web.HttpContext.Current.Items("_DALList")
        End Get
        Set(ByVal value As Dictionary(Of String, DAL))
            If Not Web.HttpContext.Current.Items.Contains("_DALList") Then
                Web.HttpContext.Current.Items.Add("_DALList", value)
            Else
                Web.HttpContext.Current.Items("_DALList") = value
            End If
        End Set
    End Property

Два вопроса: пытается ли это сериализовать объект, и если да, то как мне заставить его оставить объект нетронутым и просто ссылаться на него в памяти вместо сериализации? Мне нужно сохранить объект в целости и сохранности, поскольку он обрабатывает подключения к БД и кэширование под крышками.

[EDIT]

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

Сбой приложения w3wp.exe, версия 7.0.6001.18000, отметка времени 0x47919ed8, неисправный модуль kernel32.dll, версия 6.0.6001.18000, отметка времени 0x4791ada5, код исключения 0xe053534f, смещение ошибки 0x000000000002649d, идентификатор процесса 0x% 9, время запуска приложения 0x% 10.

и

Сервер состояний закрыл просроченное соединение TCP / IP. IP-адрес клиента - 127.0.0.1. Операция чтения с истекшим сроком действия началась в 04/07/2009 20: 44: 29.

Затем я перефразировал код, чтобы поместить элементы в объект словаря с идентификатором сеанса, и получаю эти ошибки smae. Если я использую статические переменные, это работает нормально, но у меня есть исходная проблема: пользователи будут получать доступ к данным других пользователей (очевидно, это не вариант).

Перефразированная версия выглядит следующим образом: (это работает для первого метода, но не для этого)

Shared _CurrentScope As New Dictionary(Of String, DALScope)
Public Shared Property CurrentScope() As DALScope
    Get
        If Not _CurrentScope.ContainsKey(Web.HttpContext.Current.Session.SessionID & "_CurrentScope") Then
            _CurrentScope.Add(Web.HttpContext.Current.Session.SessionID & "_CurrentScope", New DALScope)
        End If
        Return _CurrentScope(Web.HttpContext.Current.Session.SessionID & "_CurrentScope")
    End Get
    Set(ByVal value As DALScope)
        If Not _CurrentScope.ContainsKey(Web.HttpContext.Current.Session.SessionID & "_Currentscope") Then
            _CurrentScope.Add(Web.HttpContext.Current.Session.SessionID & "_Currentscope", value)
        Else
            _CurrentScope(Web.HttpContext.Current.Session.SessionID & "_Currentscope") = value
        End If
    End Set
End Property

[EDIT]

Хорошая точка зрения на блокировку в случае, когда за один и тот же сеанс выполняется более одного веб-запроса. В итоге я использовал подход httpcontext.item и обнаружил, что у меня проблемы связаны с тем, что свойство является byval, а не byref. Я изменил свой код, включив в него методы, которые обрабатывают объекты с помощью ref, и теперь это работает.

Ответы [ 3 ]

2 голосов
/ 08 апреля 2009

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

Как примечание, добавление элемента в HttpContext.Items не сериализует его. Если вы работаете с кешем, сериализация зависит от того, есть ли у вас резервное хранилище для кеша, но поскольку это зависит от кеша, это действительно зависит от выбранного вами кеша.

Редактировать

Насколько я понимаю, он возвращает ссылку на тот же экземпляр, который вы поместили в систему. Я использую HttpContext для хранения моих сессий nHibernate, в которых довольно много вещей. Работает сказочно.

0 голосов
/ 08 апреля 2009

Я могу ошибаться, но я не вижу реализованной блокировки, вы можете ожидать всевозможные проблемы, если / когда многие потоки пытаются создать / использовать / изменить объект.

0 голосов
/ 08 апреля 2009

Как уже упоминал Джош, если вы хотите кэшировать во время одного запроса, тогда httpcontext.items - это путь. Если это не работает, значит, вы делаете что-то не так, где именно вы добавляете данные в httpcontext.items? Я обычно использую httpmodule и добавляю данные в обработчик begin_request, но все зависит от того, что вы пытаетесь сделать

...