I need a singleton that:
is lazy loaded
is thread safe
loads some values at construction
those values can be queried at any time
the initialization MAY happen at some precise time, before the querying begins - so I must be able to trigger it from the outside somehow. Of course, triggering multiple times should only do the initialization once.
I use .NET 3.5.
I've started with Jon Skeet's implementation (5th version) using a static subclass:
public sealed class Singleton
{
IEnumerable<string> Values {get; private set;}
private Singleton()
{
Values = new[]{"quick", "brown", "fox"};
}
public static Singleton Instance { get { return Nested.instance; } }
private class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly Singleton instance = new Singleton();
}
}
This ticks almost all the boxes, except the "trigger initialization from outside". Since the actual initialization happens inside the ctor, it can't happen more than once.
How can this be accomplished?
The singleton will be used like this:
public static void Main(){
//do stuff, singleton should not yet be initialized.
//the time comes to initialize the singleton, e.g. a database connection is available
//this may be called 0 or more times, possibly on different threads
Singleton.Initialize();
Singleton.Initialize();
Singleton.Initialize();
//actual call to get retrieved values, should work
var retrieveVals = Singleton.Instance.Values;
}
Seems like you could do:
public sealed class Singleton
{
IEnumerable<string> Values {get; private set;}
private Singleton(bool loadDefaults)
{
if (loadDefaults)
Values = new[]{"quick", "brown", "fox"};
else
Values = new[]{"another", "set", "of", "values"};
}
public static Singleton Instance { get { return Nested.instance; } }
public static void Initialize() {
Nested.Initialize();
}
private class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly Singleton instance = new Singleton(true);
private static object instanceLock = new object();
private static bool isInitialized = false;
public static void Initialize() {
lock(instanceLock) {
if (!isInitialized) {
isInitialized = true;
instance = new Singleton(false);
}
}
}
}
}
Or to create a single instance that will be updated:
public sealed class Singleton
{
IEnumerable<string> Values {get; private set;}
private Singleton()
{
Values = new[]{"quick", "brown", "fox"};
}
public static Singleton Instance { get { return Nested.instance; } }
private static object instanceLock = new object();
private static bool isInitialized = false;
public static void Initialize() {
lock(instanceLock) {
if (!isInitialized) {
isInitialized = true;
Instance.Values = new[]{"another", "set", "of", "values"};
}
}
}
private class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly Singleton instance = new Singleton();
}
}
And the third variation based on your immutable comment and removal of Nested class comment:
public sealed class Singleton
{
IEnumerable<string> Values {get; private set;}
private Singleton()
{
Values = new[]{"quick", "brown", "fox"};
}
private static Singleton instance;
private static object instanceLock = new object();
public static Singleton Instance {
get {
Initialize();
return instance;
}
}
public static void Initialize() {
if (instance == null) {
lock(instanceLock) {
if (instance == null)
instance = new Singleton();
}
}
}
}
The first idea I had was to just use a throwaway variable assigned to the singleton's instance, which would (probably?) trigger the initialization
static Main()
{
var unused = Singleton.Instance;
//this should initialize the singleton, unless the compiler optimizes it out.
//I wonder if the compiler is smart enough to see this call has side effects.
var vals = Singleton.Instance.Values;
}
... but programming by side-effects is something I try hard to avoid, so let's make the intention a bit clearer.
public class Singleton {
public static void Initialize() {
//this accesses the static field of the inner class which triggers the private Singleton() ctor.
Instance._Initialize();
}
private void _Initialize()
{ //do nothing
}
[the rest as before]
}
so the usage would be:
static Main()
{
//still wondering if the compiler might optimize this call out
Singleton.Initialize();
var vals = Singleton.Instance.Values;
}
Btw this would also work:
static Main()
{
var vals = Singleton.Instance.Values;
}
Compiler optimization aside, I think this deals with all the requirements.
You can set up an Initialize method that can be fired from outside, if you need the initialize to happen later, but if the values are different on each time it is fired, then it cannot be static, which violates the Singleton pattern.
Based on your example, which has no variables, I assume you are just delaying when the initialization happens (routine rather than constructor), but your question suggests you want different values, but if multiple initializations happen close together, it only initializes once, so I am a bit confused on this.
I am not sure you need a Singleton only implmentation, but cannot fully answer without information on whether or not the Initialize() runs the same code every time or has some type of variable nature.
You can use double-checked locking pattern. Just add following code in you Singleton class:
public sealed class Singleton
{
..........................
private static object locker = new object();
private static bool initialized = false;
public static void Initialize() {
if (!initialized){
lock(locker) {
if (!initialized){
//write initialization logic here
initialized = true;
}
}
}
}
.......................
}
You can do something like this
public sealed class Singleton
{
IEnumerable<string> Values { get; set; }
private Singleton()
{
Console.WriteLine("-- Private Singleton constructor");
Values = new[] { "quick", "brown", "fox" };
}
public static Singleton Instance
{
get
{
Console.WriteLine("- Singleton Instance");
return Nested.instance;
}
}
public static void Initialize()
{
Console.WriteLine("- Singleton Initialize");
Nested.Initialize();
}
internal class Nested
{
private static object syncRoot = new object();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
Console.WriteLine("-- Static Nested constructor");
}
internal static readonly Singleton instance = new Singleton();
internal static void Initialize()
{
lock (syncRoot)
{
Console.WriteLine("-- Locked");
Console.WriteLine("--- Nested Initialize");
Console.WriteLine("-- Unlocked");
}
}
}
}
Usage
class Program
{
static void Main(string[] args)
{
var i = Singleton.Instance;
i = Singleton.Instance;
Console.WriteLine("-----");
Singleton.Initialize();
Singleton.Initialize();
Singleton.Initialize();
Console.Read();
}
}
Which outputs
- Singleton Instance
-- Private Singleton constructor
-- Static Nested constructor
- Singleton Instance
-----
- Singleton Initialize
-- Locked
--- Nested Initialize
-- Unlocked
- Singleton Initialize
-- Locked
--- Nested Initialize
-- Unlocked
- Singleton Initialize
-- Locked
--- Nested Initialize
-- Unlocked
public class Singleton<T> where T : class, new()
{
private static T instance;
public static T Instance
{
get
{
if (instance == null)
{
throw new Exception("singleton needs to be initialised before use");
}
return instance;
}
}
public static void Initialise(Action<T> initialisationAction)
{
lock(typeof(Singleton<T>))
{
if (instance != null)
{
return;
}
instance = new T();
initialisationAction(instance);
}
}
}
Related
I want to figure out about singleton pattern designs. I want to create seperated instances for per thread from my singleton class. So I provided two designs below.
It is Working
class Program
{
static void Main(string[] args)
{
Task.Factory.StartNew(() => Console.WriteLine(SingletonClass.Instance.GetHashCode()));
Task.Factory.StartNew(() => Console.WriteLine(SingletonClass.Instance.GetHashCode()));
Console.ReadLine();
}
}
public sealed class SingletonClass
{
[ThreadStatic]
private static SingletonClass _instance;
public static SingletonClass Instance
{
get
{
if (_instance == null)
{
_instance = new SingletonClass();
}
return _instance;
}
}
private SingletonClass()
{
}
}
It is not working (Throwing NullReferenceException and instance is not being created.)
class Program
{
static void Main(string[] args)
{
Task.Factory.StartNew(() => Console.WriteLine(SingletonClass.Instance.GetHashCode()));
Task.Factory.StartNew(() => Console.WriteLine(SingletonClass.Instance.GetHashCode()));
Console.ReadLine();
}
}
public sealed class SingletonClass
{
[ThreadStatic]
private static SingletonClass _instance = new SingletonClass();
public static SingletonClass Instance
{
get
{
return _instance;
}
}
private SingletonClass()
{
}
}
I am really wondering why an instance is not created for second design. Can anybody explain that please ?
Instead of using [ThreadStatic] then you could use ThreadLocal<T> which will essentially achieve what you're trying with [ThreadStatic].
public sealed class SingletonClass
{
private static ThreadLocal<SingletonClass> _instance;
static SingletonClass()
{
_instance = new ThreadLocal<SingletonClass>(() => new SingletonClass());
}
public static SingletonClass Instance
{
get
{
return _instance.Value;
}
}
private SingletonClass()
{
}
}
See: https://msdn.microsoft.com/en-us/library/dd642243(v=vs.110).aspx for more information.
Edit: To answer your question.
In C# when doing:
private static SingletonClass _instance = new SingletonClass();
Regardless if it's marked with [ThreadStatic] or not then it will only create a single static constructor which sets the instance of SingletonClass.
C# does not have the ability to create static constructors per threads.
That's what you can use ThreadLocal<T> for. If we take your code as an example then the default constructor for SingletonClass essentially becomes the "thread-static" constructor.
The answer to your question is mostly related to how class fields are initialized.
In the second example, the _instance field is initialized at declaration. Every time a static field is initialized at declaration, a static constructor will be created (if you don't have it declared already). At compile time, the initialization will be moved into the static constructor. This means that you will end up having something like this (didn't copy the IL code as it would be harder to understand):
public sealed class SingletonClass
{
[ThreadStatic]
private static SingletonClass _instance;
public static SingletonClass Instance
{
get
{
return _instance;
}
}
static SingletonClass()
{
_instance = new SingletonClass();
}
}
The CLR ensures that the static constructor is called only once, regardless of how many threads you have. Looking at the above code, it means that for the two Tasks that you created, the _instance field will be initialized only once (since there will be only one call to the static constructor).
i have this ObservableCollection<MyData> list that i want to insert inside my Singleton:
public sealed class Singleton
{
private static volatile Singleton instance;
private static object syncRoot = new Object();
public static ObservableCollection<MyData> list {get; set;}
private Singleton() {}
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
{
instance = new Singleton();
list = new ObservableCollection<MyData>();
}
}
}
return instance;
}
}
}
Is this the This is the right way to define it ?
I don't think it is. If the ObservableCollection should be a member of the Singleton class, instantiate it in the Singleton's private constructor. If it shouldn't, I don't see why you doing it this way. What happens when you call Singleton.list BEFORE Singleton.Instance? NullReferenceException. And since its setter is public, it can be set from outside as well which is probably not what you want.
I would modify your code like this:
public sealed class Singleton
{
private static volatile Singleton instance;
private static object syncRoot = new Object();
public ObservableCollection<MyData> list {get; private set;}
private Singleton() {
list = new ObservableCollection<MyData>();
}
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
}
I have seen different variations of objects used when acquiring a lock
A static private object
public class MyClass
{
private static object syncBlock = new object();
private void MyMethod()
{
lock (syncBlock)
{
}
}
}
A class level private object
public class MyClass
{
private object syncBlock = new object();
private void MyMethod()
{
lock (syncBlock)
{
}
}
}
using the type itself
public class MyClass
{
private void MyMethod()
{
lock (typeof (MyClass))
{
}
}
}
using this:
public class MyClass
{
private void MyMethod()
{
lock (this)
{
}
}
}
Can someone elaborate what are the pro/cons of each of these and if one should be preferred over others in a given scenario.
Don't use lock(this).
Don't use lock(typeof(MyClass)) either.
As for static vs instance, it depends on what is appropriate for you. If you use a static private object, then all instances of your class will share the lock. If you use a private object that is not static, then each instance will have its own lock. So there is no pro/cons, it depends on what you need.
I currently have a singleton, which can take up to 10 seconds to initialize. However, I don't want my users to penalized (waiting) for this initialize, so I'd rather bootstrap this component on a background thread during application startup. Here's what I have:
Singleton:
public class MySingleton
{
private static MySingleton _instance;
private static readonly object _locker = new object();
private MySingleton()
{
Init();
}
public static MySingleton Instance
{
if(_instance == null) _instance = new MySingleton();
return _instance;
}
public void Init()
{
lock(_locker)
{
if(_instance != null) return;
// long running code here...
}
}
}
Application Startup:
Task.Factory.StartNew(() => MySingleton.Instance.Init());
This code does work, guards against double init, guards against the edge case of the user needing it before it's done initializing and also guards against someone forgetting to call Init().
However, it feels a little clunky for two reasons:
a) I'm going to go into the Init method twice on startup.
b) I'd like to do threading inside the singleton, but something has to initiate the initialization.
Is there a cleaner/nicer/better way to handle this?
Thanks in advance for everyone's help.
**EDIT: As pointed out in the comments, Init was mistakenly scoped as private. It should be public and has been corrected.
Use the static constructor to trigger it and a ManualResetEvent for the syncing. It gives you a solution where everything is done within the actual class. It's therefore not dependent of that someone should call your init method.
public class MySingleton
{
private static MySingleton _instance;
private static ManualResetEvent _initEvent = new ManualResetEvent(false);
static MySingleton()
{
ThreadPool.QueueUserWorkItem(state => Init());
}
public static MySingleton Instance
{
_initEvent.Wait();
return _instance;
}
private static void Init()
{
_instance = new MySingleton();
// long running code here...
_initEvent.Set();
}
}
The event will stay signaled once triggered which means that the Instance property will return ASAP when the Init method is done.
You should define and call singleton class as below...
var instance = MySingleton.Instance;
while (true)
{
/// check for whether singleton initialization complete or not
if (MySingleton.Initialized)
{
break;
}
}
public class MySingleton
{
private static MySingleton _instance;
private static readonly object _locker = new object();
public static bool Initialized { get; set; }
private MySingleton()
{
ThreadPool.QueueUserWorkItem(call => Init());
}
public static MySingleton Instance
{
get
{
if (_instance == null)
_instance = new MySingleton();
return _instance;
}
}
private void Init()
{
lock (_locker)
{
if (Initialized)
return;
// long running code here...
for (int i = 0; i < 10000; i++)
{
}
Initialized = true;
}
}
}
I'd mybe go with a Task<T>:
class Program
{
static void Main(string[] args)
{
MySingleton.Init();
Thread.Sleep(7000);
Console.WriteLine("Getting instance...");
var mySingleton = MySingleton.Instance;
Console.WriteLine("Got instance.");
}
public class MySingleton
{
private static Lazy<MySingleton> instance;
public static MySingleton Instance
{
get { return instance.Value; }
}
public static void Init()
{
var initTask = Task.Factory.StartNew(() =>
{
for(int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
Console.WriteLine("Doint init stuff {0}...", i);
}
return new MySingleton();
});
instance = new Lazy<MySingleton>(() => initTask.Result);
}
private MySingleton() { }
}
}
I have the following static class (simplified for the sake of clarity) used in a asp.net mvc application
public static class GObjContextHelper
{
private static readonly object _lock = new object();
public static GObjContext GetObjContext()
{
Trace.TraceInformation("_lock: " + _lock);
//lock (_lock)
//{
//Trace.TraceInformation("exclusive section");
//}
return null;
}
....
}
It works perfectly fine unless the lock block is uncommented.
At that moment _lock field stops being initialized - _lock is null which can be verified with debugger or TraceInformation.
In fact both the inline and initialization using static constructor for any field stops working once lock block is present.
What makes it even stranger, this happens only within this particular class. I was unable to reproduce it in any other static class within the application.
I have a feeling that I missing something embarrassingly trivial here.
[EDIT]
It turns out (and I should have provided a more complete example in the first place..) one of the field variables was referencing GObjContextHelper.GetObjContext() internally. After fixing this circular reference everything works as expected.
I still would appreciate an explanation on what happens during initialization of a static class where field variable is an object which references the aforementioned static class in its constructor. And why lock statement has such effect on variables initialization order.
a more detailed example:
public static class GObjContextHelper
{
private static TestService testService = new TestService();
private static readonly object _lock = new object();
public static GObjContext GetObjContext()
{
Trace.TraceInformation("_lock: " + _lock);
// _lock is properly initialized if this lock block is commented out.
// otherwise _lock is null
//lock (_lock)
//{
//}
return null;
}
public static object Account { get { return testService.GetCurrentAccount(); } }
}
public class TestService
{
GObjContext context;
public AccountService()
{
context = GObjContextHelper.GetObjContext();
}
public object GetCurrentAccount()
{
return null;
}
}
You can definitely stop worrying about this by doing something like:
public static class GObjContextHelper
{
private static object _lock;
public static GObjContext GetObjContext()
{
Trace.TraceInformation("_lock: " + _lock);
lock (GetLockObject())
{
Trace.TraceInformation("exclusive section");
}
return null;
}
private static object GetLockObject()
{
if (_lock == null)
{
_lock = new object();
}
return _lock;
}
....
}
You will need to have a static constructor if you want deterministic initialization of static fields:
public static class GObjContextHelper
{
private static readonly object _lock;
static GObjContextHelper()
{
_lock = new object();
}
}
You can also force field initialization just by specifying the static constructor. This tells the c# compiler that your type is not to be marked with the beforefieldinit CIL property.
public static class GObjContextHelper
{
private static readonly object _lock = new object();
static GObjContextHelper()
{
}
}