views:

781

answers:

3

I've got an object that handles in memory caching for my data access layer (DAL) and I need to persist it between threads. From what I've read the preferred method is to use httpcontext.item with code like so:

   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

Two questions: Is this trying to serialize the object and if so how do I get it to leave the object intact and just reference it in memory instead of serializing it? I need to keep the object intact as it handles DB connections and caching under the covers.

[EDIT]

When I run this I get an error that causes the page to hang. There are two items in the event log.

Faulting application w3wp.exe, version 7.0.6001.18000, time stamp 0x47919ed8, faulting module kernel32.dll, version 6.0.6001.18000, time stamp 0x4791ada5, exception code 0xe053534f, fault offset 0x000000000002649d, process id 0x%9, application start time 0x%10.

and

The state server has closed an expired TCP/IP connection. The IP address of the client is 127.0.0.1. The expired Read operation began at 04/07/2009 20:44:29.

I then rehashed the code to put the items into a dictionary object against the session ID and I get those smae errors. If I use static variables it works fine but then I have my original problem which is that the users would be accessing other users data (clearly that's not an option).

The rehashed version is as follows: (this works for the first method but not for this one)

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]

Good point onthe locking in the case where ther is more than one webrequest under tha same session. I ended up using the httpcontext.item approach and found that I'm issues were related to the property being a byval instead of byref. I have altered my code to include methods that deal wiht hte objects by ref and now this works.

+1  A: 

HttpContext exists within the lifetime of a single request. I assume by threads here you are talking about maintaining the state accross multiple requests. If so HttpContext.Items is not what you want. You would want to use the Application Cache, or some other caching mechanism.

As a side note putting an item into HttpContext.Items does not serialize it. If you go with a cache serialization depends on if you have a backing store for the cache, but since this is cache specific it really depends on the cache you choose.

Edit

My understanding is that it returns a reference to the same instance you put into the system. I use HttpContext to store my nHibernate sessions in which is quite a lot of stuff. Works fabulous.

JoshBerke
I only need the object during hte one request. However now that I've put it into the the collection it does not work correctly. does the collection return a copy of the object (byval) or the object itself (byref)?
Middletone
A: 

As Josh already mentioned, if you want to cache during a single request, then httpcontext.items is the way to go. If this is not working then you must be doing something wrong, where exactly do you add the data to httpcontext.items? I usually use an httpmodule and add the data in the begin_request handler but it all depends on what you're trying to do

Waleed Eissa
A: 

I might be wrong, but I do not see any locking implemented, you might expect all sorts of problems if/when many threads try to create/use/change the object.

Sunny