I have singleton that fetches from DB, hence it is expensive load. It is lazy loaded.
I would like to create a method that refreshes that singleton and populates it once it is required.
the data is DB and very expensive, so I want to refresh it only once in case I have concurrent calls. (that is, if I get 500 calls to refresh, I want to restart the refresh only once)
public static PageData Instance
{
get
{
if (m_Instance == null)
{
lock (instanceLock)
{
if (m_Instance == null)
{
m_Instance = new PageData();
}
}
}
return m_Instance;
}
}
public void ReSync()
{
lock (instanceLock)
{
/* Setting to null to force the Instance to re-build */
m_Instance = null;
PageData pData = Instance;
}
}
thanks
From your singleton class, if the object is created then no objects are allowed to modify the someNum & someString values because of a singleton pattern.
The true, non monobehaviour singleton can't really be destroyed or reinitialized as the static field is read only. If you need this you have to do the usual singleton approach with a normal private static variable. To force a reinitialization you just add a method "Destroy" which sets the static reference to "null".
Singleton Class allow for single allocations and instances of data. It has normal methods and you can call it using an instance. To prevent multiple instances of the class, the private constructor is used.
If you have a regular object that you can't deinitialize it's a memory problem. Singletons are no different, except that you have to write a function to do it. Singletons have to be completely self managed. This means from init to deinit.
This is slightly incorrect, your
if (m_Instance == null)
should really be on the inside of the lock.
Sorry, didn't spot that.
Nothing is built in that can make other clients abandon calls silently if you are already refreshing. Timeouts will generate an exception I think. Perhaps maintain a stale DateTime that you can check to avoid doing the refresh on queued callers.
In my understanding this should work.
Here is my code:
private static instanceLock = new object();
private static _refreshing = true;
public static PageData Instance
{
get
{
if (_refreshing)
{
lock (instanceLock)
{
if (_refreshing)
{
m_Instance = new PageData();
_refreshing = false; //now allow next refreshes.
}
}
}
return m_Instance;
}
}
public void ReSync()
{
if (!_refreshing)
lock (instanceLock)
{
if (!_refreshing)
{
_refreshing = true; //don't allow refresh until singleton is called.
}
}
}
Aside from the double-checked locking being broken (correction, apparently it does work but I still find it not particularly pretty), if you have write access to m_Instance why not just set it to new PageData() there and then in ReSync?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With