2

I haven't used singleton before, so maybe I have the complete wrong idea, but I thought the point was that it can only be initialized once, and anyone calling it will reference the same instance..?

So I took this from an example. GetInstance() is called from hundred different places in my program, and when I debug, the line "Prog = New Program" keeps getting hit for each of those calls. Which I thought was exactly what should NOT happen.. Or do I have some fundamental misunderstanding?

    ' ********************** THREAD SAFE SINGLETON **************************
 Public Class Program 

    Private Shared Prog As Program = Nothing
    Private Shared ReadOnly singletonLock As New Object()
    Public Shared Function GetInstance() As Program
        SyncLock singletonLock
            If Prog Is Nothing Then
                Prog = New Program
            End If
            Return Prog
        End SyncLock
    End Function

EDIT:

It seems the "New" sub triggers a number of calls to Program.GetInstance, before the first one completes. This is due to me earlier having lots of shared public objects in this class, which are no longer shared since the class was made singleton. And these objects, when initialized, calls the Program class for reference to other of it's objects.

bretddog
  • 5,411
  • 11
  • 63
  • 111
  • if `Prog` keeps getting reinstantiated all the time, what is setting it to `Nothing`? Shouldn't The `Program` class have a private constructor too, so that the only way to instantiate it is through `GetInstance()`? – Jodrell Jun 27 '12 at 16:34
  • 3
    Jon Skeet's article on singletons is a good reference: http://csharpindepth.com/Articles/General/Singleton.aspx – Dan Busha Jun 27 '12 at 16:44
  • @Jodrell. I can't see any other code setting it to Nothing. Yes it has a private constructor, it's below the code I selected, hence invisible :) – bretddog Jun 27 '12 at 16:45
  • @Dan Busha, if you are happy with c# that is a good reference, I was about to post myself. – Jodrell Jun 27 '12 at 17:12
  • Does the `Program` class have a `Sub Main()` for a console app? – Jodrell Jun 27 '12 at 17:16
  • Perhaps you need to add a static constructor `Shared Sub New() ... End Sub` – Jodrell Jun 27 '12 at 17:26
  • Dude you did not test what you posted? – paparazzo Jun 28 '12 at 02:51
  • @Blam, test what? you're not very specific, but it requires a fundamental redesign of my code, so takes some time. But my explanation should be obvious enough for anyone to judge if this is a fundamental incorrect use of a singleton constructor to there initialize objects that reference the same singleton. If I remove all the code inside that constructor then of course the program runs, but it has no functionality as all the startup logic is stripped. So I'm rethinking this design now. – bretddog Jun 28 '12 at 03:30
  • Easy, yes what you posted is a shell. If the posted does not fail then how can SO help? The common practice is to reduce code to the most simple version that fails. – paparazzo Jun 28 '12 at 12:56
  • So, what's the point of your comments..? – bretddog Jun 28 '12 at 13:23

2 Answers2

1

Guess the answer will be this:

It seems the "New" sub triggers a number of calls to Program.GetInstance, before the first one completes. This is due to me earlier having lots of shared public objects in this class, which are no longer shared since the class was made singleton. And these objects, when initialized, calls the Program class for reference to other of it's objects. So; a circular reference.

bretddog
  • 5,411
  • 11
  • 63
  • 111
0

This is cribbed from c# but might work a little better (post code should work though.)

Public NotInheritable Class Singleton
    Private Shared ReadOnly Singleton instance = new Singleton();

    ' Explicit static constructor to tell compiler
    ' not to mark type as beforefieldinit
    Shared Sub New()
    End Sub

    Private Sub New()
    End Sub

    Public Shared ReadOnly Property Instance As Singleton
        Get
            return Me.instance;
        End Get
    End Property
End Class

Should work nicely without any locking but, as Skeet says, could be lazier.

Jodrell
  • 34,946
  • 5
  • 87
  • 124