Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to refresh singleton in C#

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

like image 969
Himberjack Avatar asked Mar 16 '11 13:03

Himberjack


People also ask

Can you modify a singleton?

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.

How do you destroy a singleton?

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".

What is singleton in C sharp?

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.

Can we de init a singleton object in Swift?

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.


3 Answers

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.

like image 61
Adam Houldsworth Avatar answered Oct 11 '22 20:10

Adam Houldsworth


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.
                    }
                }
        }
like image 38
Tengiz Avatar answered Oct 11 '22 19:10

Tengiz


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?

like image 28
Massif Avatar answered Oct 11 '22 20:10

Massif