clarification on Shared class constructor

P

Paul Wu

From what I understand, in ASP.NET, each HTTP requests is serviced by a separate thread. So if my code uses a static Class with shared members and properties, I can manage concurrent access by using something like the Monitor or ReaderWriterLock class. It is rather difficult to simulate multiple threads in a debug environment so I am hoping someone can enlighten me by telling me what happens in the following scenario?



A request is made to the IIS which in turn launches a thread to access a shared member MyCollection.Count. Since the class has not been initialized, the Constructor is invoked and initializes class with some data from the database. Before the first thread exits the constructor, a second request is made to the IIS which spawns a second thread to call MyCollection.Count.

Will the second thread: (1) tries to invoke the constructor again, (2) waits till the first thread is finished before it enters MyCollection.Count, (3) gets access to MyCollection.Count and get a zero (or a number less than the actual count) because the collection is not fully initialized yet.



Public Class MyCollection
Private Shared mCollection as New Hashtable



Public Shared Function Count() as Integer
Return mCollection.Count
End Function



Shared Sub New
'code to initialize a datatable
For each record in datatable
Dim obj as New Employee(record.column("name"))
mCollection.Add(key, obj)
Next
End Sub

End Class



Should I be doing something like the following:





Public Classs MyCollection
Private Shared mCollection as New Hashtable

Private Shared Lock As New System.Threading.ReaderWriterLock


Public Shared Function Count() as Integer

Lock.AcquireReaderLock(Timeout.Infinite)

Count = mCollection.Count
Lock.ReleaseReaderLock()
End Function



Shared Sub New


Try

Lock.AcquireWriterLock(Timeout.Infinite)

'code to initialize a datatable

...
For each record in datatable
Dim obj as New Employee(record.column("name"))
mCollection.Add(key, obj)
Next
Finally

Lock.ReleaseWriterLock()
End Try

End Sub

End Class
 
K

Karl Seguin

Paul:
Static constructors are thread-safe, no if or buts about it. That means,
from a static constructor point of view, you are assured that...the only
thing you need to worry about is if your static constructor relies on a 2nd
static constructor which has a reference back to the 1st class (cyclical
reference)...otherwise your safe.

As for as your properties, they aren't thread-safe...unless the underlying
class itself is (some .net classes are thread safe).

You should take a look at:
http://odetocode.com/Articles/313.aspx
and
http://odetocode.com/Articles/314.aspx

As you hopefully know, locks come with a hefty performance price and you
should consider alternatives if possible...I haven't had the need to use
static fields too often...

Karl

--
MY ASP.Net tutorials
http://www.openmymind.net/ - New and Improved (yes, the popup is
annoying)
http://www.openmymind.net/faq.aspx - unofficial newsgroup FAQ (more to
come!)
From what I understand, in ASP.NET, each HTTP requests is serviced by a
separate thread. So if my code uses a static Class with shared members and
properties, I can manage concurrent access by using something like the
Monitor or ReaderWriterLock class. It is rather difficult to simulate
multiple threads in a debug environment so I am hoping someone can enlighten
me by telling me what happens in the following scenario?

A request is made to the IIS which in turn launches a thread to access a
shared member MyCollection.Count. Since the class has not been initialized,
the Constructor is invoked and initializes class with some data from the
database. Before the first thread exits the constructor, a second request is
made to the IIS which spawns a second thread to call MyCollection.Count.

Will the second thread: (1) tries to invoke the constructor again, (2) waits
till the first thread is finished before it enters MyCollection.Count, (3)
gets access to MyCollection.Count and get a zero (or a number less than the
actual count) because the collection is not fully initialized yet.


Public Class MyCollection
Private Shared mCollection as New Hashtable

Public Shared Function Count() as Integer
Return mCollection.Count
End Function

Shared Sub New
'code to initialize a datatable
For each record in datatable
Dim obj as New Employee(record.column("name"))
mCollection.Add(key, obj)
Next
End Sub
End Class

Should I be doing something like the following:


Public Classs MyCollection
Private Shared mCollection as New Hashtable
Private Shared Lock As New System.Threading.ReaderWriterLock

Public Shared Function Count() as Integer
Lock.AcquireReaderLock(Timeout.Infinite)
Count = mCollection.Count
Lock.ReleaseReaderLock()
End Function

Shared Sub New

Try
Lock.AcquireWriterLock(Timeout.Infinite)
'code to initialize a datatable
...
For each record in datatable
Dim obj as New Employee(record.column("name"))
mCollection.Add(key, obj)
Next
Finally
Lock.ReleaseWriterLock()
End Try
End Sub
End Class
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top