Thread safe singleton

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Eric

    #1

    Thread safe singleton

    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(Option al ByVal UniqueKey As
    String = "") As RuleManager
    Get
    If mInnerList.Cont ains(UniqueKey) Then
    Return DirectCast(mInn erList(UniqueKe y), RuleManager)
    End If

    SyncLock mInnerList.Sync Root
    If Not mInnerList.Cont ains(UniqueKey) Then
    mInnerList(Uniq ueKey) = New RuleManager
    End If
    Return DirectCast(mInn erList(UniqueKe y), RuleManager)
    End SyncLock

    End Get
    End Property
    End class


  • Joseph Ferris

    #2
    Re: Thread safe singleton

    Eric,

    Have you considered something along these lines for your instance
    property? (Assume Imports System.Web.Http Context, 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 ("RuleManage r") 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 ("RuleManage r") = _Instance

    Else

    '// Retrieve the instance that currently exists in the
    session.
    _Instance = CType(Current.S ession("RuleMan ager"),
    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

    Comment

    • Eric

      #3
      Re: Thread safe singleton

      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


      "Joseph Ferris" <joseph.ferris@ gmail.com> wrote in message
      news:1129234475 .202622.109350@ g44g2000cwa.goo glegroups.com.. .[color=blue]
      > Eric,
      >
      > Have you considered something along these lines for your instance
      > property? (Assume Imports System.Web.Http Context, 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 ("RuleManage r") 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 ("RuleManage r") = _Instance
      >
      > Else
      >
      > '// Retrieve the instance that currently exists in the
      > session.
      > _Instance = CType(Current.S ession("RuleMan ager"),
      > 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
      >[/color]


      Comment

      • Joseph Ferris

        #4
        Re: Thread safe singleton

        Eric,

        Gotcha. Sorry I couldn't be of further assistance.

        Joseph

        Comment

        • Brian Gideon

          #5
          Re: Thread safe singleton

          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

          Eric wrote:[color=blue]
          > 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(Option al ByVal UniqueKey As
          > String = "") As RuleManager
          > Get
          > If mInnerList.Cont ains(UniqueKey) Then
          > Return DirectCast(mInn erList(UniqueKe y), RuleManager)
          > End If
          >
          > SyncLock mInnerList.Sync Root
          > If Not mInnerList.Cont ains(UniqueKey) Then
          > mInnerList(Uniq ueKey) = New RuleManager
          > End If
          > Return DirectCast(mInn erList(UniqueKe y), RuleManager)
          > End SyncLock
          >
          > End Get
          > End Property
          > End class[/color]

          Comment

          • Dennis

            #6
            Re: Thread safe singleton

            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!
            --
            Dennis in Houston


            "Eric" wrote:
            [color=blue]
            > 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
            >
            >
            > "Joseph Ferris" <joseph.ferris@ gmail.com> wrote in message
            > news:1129234475 .202622.109350@ g44g2000cwa.goo glegroups.com.. .[color=green]
            > > Eric,
            > >
            > > Have you considered something along these lines for your instance
            > > property? (Assume Imports System.Web.Http Context, 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 ("RuleManage r") 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 ("RuleManage r") = _Instance
            > >
            > > Else
            > >
            > > '// Retrieve the instance that currently exists in the
            > > session.
            > > _Instance = CType(Current.S ession("RuleMan ager"),
            > > 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
            > >[/color]
            >
            >
            >[/color]

            Comment

            • Eric

              #7
              Re: Thread safe singleton

              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



              "Dennis" <Dennis@discuss ions.microsoft. com> wrote in message
              news:87242E57-EFC3-44E6-A752-C3115F950EFB@mi crosoft.com...[color=blue]
              > 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!
              > --
              > Dennis in Houston
              >
              >
              > "Eric" wrote:
              >[color=green]
              >> 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
              >>
              >>
              >> "Joseph Ferris" <joseph.ferris@ gmail.com> wrote in message
              >> news:1129234475 .202622.109350@ g44g2000cwa.goo glegroups.com.. .[color=darkred]
              >> > Eric,
              >> >
              >> > Have you considered something along these lines for your instance
              >> > property? (Assume Imports System.Web.Http Context, 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 ("RuleManage r") 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 ("RuleManage r") = _Instance
              >> >
              >> > Else
              >> >
              >> > '// Retrieve the instance that currently exists in the
              >> > session.
              >> > _Instance = CType(Current.S ession("RuleMan ager"),
              >> > 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
              >> >[/color]
              >>
              >>
              >>[/color][/color]


              Comment

              • Brian Gideon

                #8
                Re: Thread safe singleton

                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

                Dennis wrote:[color=blue]
                > 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!
                > --
                > Dennis in Houston
                >
                >[/color]

                Comment

                • Eric

                  #9
                  Re: Thread safe singleton

                  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" <briangideon@ya hoo.com> wrote in message
                  news:1129297502 .761482.281460@ z14g2000cwz.goo glegroups.com.. .[color=blue]
                  > 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
                  >
                  > Dennis wrote:[color=green]
                  >> 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!
                  >> --
                  >> Dennis in Houston
                  >>
                  >>[/color]
                  >[/color]


                  Comment

                  • Brian Gideon

                    #10
                    Re: Thread safe singleton

                    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.Sync Root
                    If Not mInnerList.Cont ains(UniqueKey) Then
                    mInnerList(Uniq ueKey) = New RuleManager
                    End If
                    Return DirectCast(mInn erList(UniqueKe y), 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

                    Eric wrote:[color=blue]
                    > 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
                    >
                    >[/color]

                    Comment

                    • Dennis

                      #11
                      Re: Thread safe singleton

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


                      "Eric" wrote:
                      [color=blue]
                      > 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" <briangideon@ya hoo.com> wrote in message
                      > news:1129297502 .761482.281460@ z14g2000cwz.goo glegroups.com.. .[color=green]
                      > > 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
                      > >
                      > > Dennis wrote:[color=darkred]
                      > >> 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!
                      > >> --
                      > >> Dennis in Houston
                      > >>
                      > >>[/color]
                      > >[/color]
                      >
                      >
                      >[/color]

                      Comment

                      • m.posseth

                        #12
                        Re: Thread safe singleton

                        [color=blue]
                        >, I'm not sure excatly how many times the dll
                        > would get loaded. I'm assuming the dll would only get loaded once[/color]

                        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]



                        "Eric" <anywhere@usa.c om> wrote in message
                        news:eglpdRM0FH A.3588@tk2msftn gp13.phx.gbl...[color=blue]
                        > 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
                        >
                        >
                        >
                        > "Dennis" <Dennis@discuss ions.microsoft. com> wrote in message
                        > news:87242E57-EFC3-44E6-A752-C3115F950EFB@mi crosoft.com...[color=green]
                        >> 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!
                        >> --
                        >> Dennis in Houston
                        >>
                        >>
                        >> "Eric" wrote:
                        >>[color=darkred]
                        >>> 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
                        >>>
                        >>>
                        >>> "Joseph Ferris" <joseph.ferris@ gmail.com> wrote in message
                        >>> news:1129234475 .202622.109350@ g44g2000cwa.goo glegroups.com.. .
                        >>> > Eric,
                        >>> >
                        >>> > Have you considered something along these lines for your instance
                        >>> > property? (Assume Imports System.Web.Http Context, 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 ("RuleManage r") 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 ("RuleManage r") = _Instance
                        >>> >
                        >>> > Else
                        >>> >
                        >>> > '// Retrieve the instance that currently exists in the
                        >>> > session.
                        >>> > _Instance = CType(Current.S ession("RuleMan ager"),
                        >>> > 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
                        >>> >
                        >>>
                        >>>
                        >>>[/color][/color]
                        >
                        >[/color]


                        Comment

                        Working...