0

I have a static DataLibrary class that implements a singleton pattern.

        public static FacilityRepository FacilRepo
        {
            get
            {
                if (_facilRepo == null)
                {
                    _facilRepo = new FacilityRepository(Authenticated.UserId);
                    if (Authenticated.FacKey.Length > 0)
                    {
                        foreach (var fac in _facilRepo)
                            fac.IsSelected = (fac.FacilityKey == Authenticated.FacKey);                        
                    }
                }
                return _facilRepo;
            }
        }

private static FacilityRepository _facilRepo;

When I access this from different threads using Task.Factory.StartNew the FacilityReposity gets recreated multiple times how can I avoid this.

Wegged
  • 2,383
  • 20
  • 26
  • If you are creating many new threads at the same time and they are all trying to access the FacilRepo property.. it may be because there is no locking around the property. Take a look at http://en.csharp-online.net/Singleton_design_pattern%3A_Thread-safe_Singleton (right at the bottom) – WiseGuyEh Mar 17 '11 at 15:03

3 Answers3

9

I don't think you've actually got a thread-local variable here - you've just got a race condition because you're not implementing the singleton pattern properly.

I have a page about the singleton pattern which gives some better options. (In particular, as you're using the TPL you must be using .NET 4, so the Lazy<T> option is definitely a contender.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • excellent Article!!!! Thank you . Ill accept your answer as soon as it lets me 4 more minutes. – Wegged Mar 17 '11 at 15:11
2

This Article by Jon Skeet might be helpful: Implementing the Singleton Pattern in C#

These questions might be helpful too:

Community
  • 1
  • 1
gideon
  • 19,329
  • 11
  • 72
  • 113
0

This would happen if multiple threads access your property for the first time, before _facilRepo is initialised. You have to lock the initialisation code like this:

private static object _facilRepoLock = new object();
public static FacilityRepository FacilRepo
{
    get
    {
        if (_facilRepo == null)
        {
            lock (_facilRepoLock)
            {
                if (_facilRepo == null)
                {
                    _facilRepo = new FacilityRepository(Authenticated.UserId);
                    if (Authenticated.FacKey.Length > 0)
                    {
                        foreach (var fac in _facilRepo)
                            fac.IsSelected = (fac.FacilityKey == Authenticated.FacKey);
                    }
                }
            }
        }
        return _facilRepo;
    }
}

private static FacilityRepository _facilRepo;
Artiom Chilaru
  • 11,811
  • 4
  • 41
  • 52
  • 2
    Without the variable being volatile, I'm not sure that's genuinely thread-safe. There are simpler ways of achieving thread-safety than using double-checked locking. – Jon Skeet Mar 17 '11 at 15:05
  • Ahh, interesting.. I didn't know that before.. Your article is an eye-opener :) – Artiom Chilaru Mar 17 '11 at 15:10