3

The following code is excerpted from the (Windows Identity Foundation SDK) template that MS uses to create a new Security Token Service Web Site.

public static CustomSecurityTokenServiceConfiguration Current  
{  
    get  
    {
        var key = CustomSecurityTokenServiceConfigurationKey;

        var httpAppState = HttpContext.Current.Application;

        var customConfiguration = httpAppState.Get(key)
            as CustomSecurityTokenServiceConfiguration;  

        if (customConfiguration == null)
        {  
            lock (syncRoot)
            {
                customConfiguration = httpAppState.Get(key)
                    as CustomSecurityTokenServiceConfiguration;  

                if (customConfiguration == null)
                {
                    customConfiguration =
                        new CustomSecurityTokenServiceConfiguration();  
                    httpAppState.Add(key, customConfiguration);
                }
            }
        }    
        return customConfiguration;  
    }
}

I'm relatively new to multi-threaded programming. I assume that the reason for the lock statement is to make this code thread-safe in the event that two web requests arrive at the web site at the same time.

However, I would have thought that using lock (syncRoot) would not make sense because syncRoot refers to the current instance that this method is operating on... but this is a static method!

How does this make sense?

Steven
  • 166,672
  • 24
  • 332
  • 435
Vivian River
  • 31,198
  • 62
  • 198
  • 313
  • @Paolo: That's a good question. Having said that, I assume its either a `static` variable or returned by a Singleton given its name. – Powerlord May 18 '10 at 15:42
  • @Bemrose: The assumption I've made is that `syncRoot` is a static class field that always holds the same instance: `private readonly object syncRoot = new object();`. Of course `syncRoot` could be defined as follows: `private object syncRoot { get { return new object(); } }`. In that case, we'd be in trouble :-) – Steven May 18 '10 at 15:46

1 Answers1

6

The C# lock statement does not lock on a method, but on the object it is supplied to. In your case syncRoot. Because there is only one instance of this syncRoot object, this ensures the CustomSecurityTokenServiceConfiguration class will only get created once for that app domain. So the property can be called in and executed in parallel. However, the block within the lock { ... } will never be called in parallel. However, it can be called multiple times and that is what the extra if (customConfiguration == null) statement is doing within the lock block. This mechanism is called a double checked lock.

Steven
  • 166,672
  • 24
  • 332
  • 435
  • OK. Upon more carefully looking at this code, I see that `syncRoot` is declared as a static object. I was just a bit confused because I'm used to seeing `syncRoot` appear as a member of the .net enumeration classes. It looks like this block of code is the only place that the `syncRoot` is used, so it must have been declared for the express purpose of locking the block of code. – Vivian River May 18 '10 at 16:29
  • This is the common way to do locking using the `lock` keyword in .NET: Create a private readonly `Object` and use it as object to lock on. – Steven May 18 '10 at 19:25