public static/shared read only properties in global.asax

  • Thread starter Thread starter Gary Bagen
  • Start date Start date
G

Gary Bagen

If I add a shared/static read only property to the Global class of
global.asax, do I need to implement thread locking like the
Application object does?

There are two ways I want to do things, Initialize a private variable
on application_start for Web.Config value. And load the data the first
time the property is read for xml files or database loads.

I like the idea of holding static info in Web.Config/Database and
seeing that data in the rest of the app as Global.variable syntax.

Public Class Global
Inherits System.Web.HttpApplication

Private Shared sLocalTitle As String

Public Shared ReadOnly Property Title() As String
Get
'This was initialized on application_start
Return sLocalTitle
End Get
End Property

Sub Application_Start(ByVal sender As Object, ByVal e As
EventArgs)
' Fires when the application is started
sLocalTitle = ConfigurationSettings.AppSettings("Title")
End Sub

Public Shared ReadOnly Property BookList() As DataSet
Get
Dim dsBookList As DataSet

'Is any thread locking required here? Regardless or dependant on using
the
'Cache object?
dsBookList = CType(HttpRuntime.Cache.Get("dsBookList"),
DataSet)

If dsBookList Is Nothing Then
'Cache is empty, now go get data from source

dsBookList = New DataSet

'Read from File or Database
Dim sPath As String =
HttpContext.Current.Server.MapPath("~/BookList.xml")
dsBookList.ReadXml(New StreamReader(strPath))

'Add to Cache
HttpRuntime.Cache.Insert("dsBookList", dsBookList)

End If

Return dsBookList

End Get
End Property

End Class
 
Gary Bagen said:
If I add a shared/static read only property to the Global class of
global.asax, do I need to implement thread locking like the
Application object does?

Any time you can have multiple threads, especially multiple page requests,
accessing the same object, you have to handle any synchronization issues.

....
Public Class Global
Inherits System.Web.HttpApplication

Private Shared sLocalTitle As String

Public Shared ReadOnly Property Title() As String
Get
'This was initialized on application_start
Return sLocalTitle
End Get
End Property

In this case, you don't need any locking, since the property is read-only
and since strings are immutable. The only possible issue would be a
situation where the application is restarting and one thread gets the old
title while Application_Start is setting the new one. I'm not sure whether
ASP.NET prevents this or not for page request threads, but it surely can't
prevent it for threads you may spawn from a page request.

....
Public Shared ReadOnly Property BookList() As DataSet
Get
Dim dsBookList As DataSet

'Is any thread locking required here? Regardless or dependant on using
the
'Cache object?

Yes. Even if only your code is touching Cache("dsBookList"), you still have
an issue if more than one thread is calling the property while
Cache("dsBookList") is Nothing. What happens if two threads see dsBookList
as Nothing and both execute "dsBookList = New DataSet"? That's a classic
race condition, like "i = i + 1".

Of course, you also need to use locking if you modify the dataset itself.
 
Thanks for the reply, this really helps.

I am trying to simplify the use of the Session, Application and Cache
objects for our developers. Most of our developers are just breaking
the ice with ASP let alone ASP.NET. I'd like to make the applications
more programmable and readable by using Global.StrongName instead of
CType(Application("Icouldspellthiswrong"),ObjectType)

However, the code to implement synchronization is probably too complex
to introduce at this point.

So what I am thinking is having application-wide data load into the
Cache on Application Start (just like the data from Web.Config) and
change those properties to Read Only. As each application instance
gets its own Cache object, we should be safe there.

For variables that the developer wanted to update I was thinking of
wrapper properties over the Application and Session objects. As these
guys having multithreading support built in, could I accomplish the
following?

'Using the Application object
Public Shared Property ReadWriteValue() As Integer
'Use the Application object as it handles reading and
'writing of values in a multithreaded environment.
Get
Return CType(HttpContext.Current.Application("intReadWriteValue"),
Integer)
End Get
Set(ByVal Value As Integer)
HttpContext.Current.Application("intReadWriteValue") =
Value
End Set
End Property

'Using the Session object (this property could also be moved to the
specific page(s) that use the dataset)
Public Shared Property ReadWriteUserDataset() As DataSet
'Use the Session object as it handles reading and
'writing of values in a multi-threaded environment.
Get
Return CType(HttpContext.Current.Session("dsUserDataset"),
DataSet)
End Get
Set(ByVal Value As DataSet)
HttpContext.Current.Session("dsUserDataset") = Value
End Set
End Property
 
Back
Top