Thread safe singleton

E

Eric

I have a VB.net dll project with a class that is a singleton. I've been
using this in winform apps without any problems. I would like to use this
same dll in a web form project but my singleton will cause problems because
some sessions may need different values in the singleton. I want to change
my singleton to store a private hashtable with different instances. I guess
this is more like a factory pattern now but that doesn't matter My main
concern is about thread safty. The code below is what I have so far. Is
this the correct way to protect access to the inner hashtable? Thanks for
the comments or suggestions.

Eric


Friend NotInheritable Class RuleManager
Private Shared mInnerList As new HashTable
Private Sub New()
'hide constructor
End Sub

Public Shared ReadOnly Property Instance(Optional ByVal UniqueKey As
String = "") As RuleManager
Get
If mInnerList.Contains(UniqueKey) Then
Return DirectCast(mInnerList(UniqueKey), RuleManager)
End If

SyncLock mInnerList.SyncRoot
If Not mInnerList.Contains(UniqueKey) Then
mInnerList(UniqueKey) = New RuleManager
End If
Return DirectCast(mInnerList(UniqueKey), RuleManager)
End SyncLock

End Get
End Property
End class
 
J

Joseph Ferris

Eric,

Have you considered something along these lines for your instance
property? (Assume Imports System.Web.HttpContext, and _Instance is a
private member declaration of your class.)

Public Shared ReadOnly Property Instance() As RuleManager

'// Check to see if a session variable with the signature of
the
'// current singleton object exists.
If Current.Session("RuleManager") Is Nothing Then

'// Create a new instance of the object.
_Instance = New RuleManager

'// Store the object in the session, using the signature
declared
'// to retrieve it when requested.
Current.Session("RuleManager") = _Instance

Else

'// Retrieve the instance that currently exists in the
session.
_Instance = CType(Current.Session("RuleManager"),
RuleManager)

End If

'// Return the singular session instance of the singleton,
whether
'// it was created or retrieved from the session.
Return _Instance

End Function

You are basically creating a Singleton for each individual user and
storing it in their Session. You don't have to worry about
cross-polluting the session now.

HTH,

Joseph
 
E

Eric

Joseph,

Thanks for your suggestion. I would use that approach but the dll that I
currently have has the RuleManager scoped as Friend. This class is internal
to my dll. Basically all of my classes in the dll need to be able to work
with this RuleManager but the RuleManager may need to be different for each
session. Remember this dll needs to work with both web apps and winforms.

Thanks,

Eric
 
B

Brian Gideon

Eric,

It is thread-safe, but only because the Hashtable is unique in that it
can safely support one writer and multiple readers simultaneously.

Brian
 
G

Guest

If it's a singleton, won't all apps using the dll share the same hashtable
since there is only one instance of the class? Also, I thought you had to
use synclock for reads as well as writes for threadsafe classes. Sorry, I'm
just learning!
 
E

Eric

Dennis,

My understanding is that the dll will get loaded once for each win app. I
beleive there would be a new singleton for each of this apps becuase of
that. As for an asp.net app, I'm not sure excatly how many times the dll
would get loaded. I'm assuming the dll would only get loaded once. This is
the situation where I would need to make use of the hashtable so that each
session could get a different instance of the singleton.

Thanks,

Eric
 
B

Brian Gideon

Dennis,

No, applications do not share objects or any other data from the dll.
Each application will execute the code in the dll independently of the
others so they will all be working with different instances of the
hashtable.

Yes, generally speaking you do have to use a lock for both reads and
writes for the code to be thread-safe. There are exceptions though.
In this particular case the code is thread-safe because 1) the
Hashtable can support one writer and multiple readers concurrently and
2) items are never removed from the Hashtable. The Hashtable is the
only collection in the .NET Framework that has partial thread-safety.

In general, I would avoid the practice of attempting to access data
structures without locks in this manner. Subtle problems might crop up
when the code is ran on different platforms or framework versions.

Brian
 
E

Eric

Brian,

I didn't really think about it yet until your message but I will have to
add a method to remove from the hashtable at some point. Do you have any
examples of a thread safe way to read and write to any colletcion? I may
want to change the hashtable implementation at some point.

Thanks,

Eric



Brian Gideon said:
Dennis,

No, applications do not share objects or any other data from the dll.
Each application will execute the code in the dll independently of the
others so they will all be working with different instances of the
hashtable.

Yes, generally speaking you do have to use a lock for both reads and
writes for the code to be thread-safe. There are exceptions though.
In this particular case the code is thread-safe because 1) the
Hashtable can support one writer and multiple readers concurrently and
2) items are never removed from the Hashtable. The Hashtable is the
only collection in the .NET Framework that has partial thread-safety.

In general, I would avoid the practice of attempting to access data
structures without locks in this manner. Subtle problems might crop up
when the code is ran on different platforms or framework versions.

Brian
 
B

Brian Gideon

Eric,

Change the Instance property so that it acquires a lock everytime like
the following.

Public Shared ReadOnly Property Instance( _
Optional ByVal UniqueKey As String = "") As RuleManager
Get

SyncLock mInnerList.SyncRoot
If Not mInnerList.Contains(UniqueKey) Then
mInnerList(UniqueKey) = New RuleManager
End If
Return DirectCast(mInnerList(UniqueKey), RuleManager)
End SyncLock

End Get
End Property

Also, wrap a SyncLock around everything in the method that will remove
from the collection as well.

Brian
 
G

Guest

Thanks for taking the time to explain the singleton.
--
Dennis in Houston


Eric said:
Brian,

I didn't really think about it yet until your message but I will have to
add a method to remove from the hashtable at some point. Do you have any
examples of a thread safe way to read and write to any colletcion? I may
want to change the hashtable implementation at some point.

Thanks,

Eric
 
M

m.posseth

, I'm not sure excatly how many times the dll
would get loaded. I'm assuming the dll would only get loaded once

Be aware that there can be multiple ASP.Net Worker threads starting your app
at the same time , on my webserver the webserver starts my projects 4 times
( i receive a e-mail when my singleton is created ) so your assumination
that it might get started once can be wrong .

regards

Michel Posseth [MCP]
 

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

Top