简体   繁体   中英

ASP.NET Threading - Double checked locking

I have an extension method on the HttpApplicationState object for getting my IoC container out of the application. This same code will also create the container if it doesn't exist.

I have 2 questions:

  1. Is my code actually thread safe as I intend it to be
  2. Is this considered the best practice for dealing with the application state

Code as follows:

private const string GlobalContainerKey = "UnityContainerKey";

public static IUnityContainer GetContainer(this HttpApplicationState application)
{
    var container = application[GlobalContainerKey] as IUnityContainer;

    if (container == null)
    {
        try
        {
            application.Lock();
            container = application[GlobalContainerKey] as IUnityContainer;

            if (container == null)
            {
                container = new UnityContainer();
                application[GlobalContainerKey] = container;
            }
        }
        finally
        {
            application.UnLock();
        }
    }

    return container;
}

You need to put

var container = application[GlobalContainerKey] as IUnityContainer;

in the lock as well, otherwise many threads may create a new container in sequence.

private const string GlobalContainerKey = "UnityContainerKey";
private const object lockObject = new object();

public static IUnityContainer GetContainer(this HttpApplicationState application)
{
    var IUnityContainer container = null;

    lock (lockObject)
    {
        container = application[GlobalContainerKey] as IUnityContainer;
        if (container == null)
        {
            container = new UnityContainer();
            application[GlobalContainerKey] = container;
        }
    }

    return container;
}

Technically, that won't work given the EMCA specification. Jon Skeet goes into this in his C# FAQ:

http://www.yoda.arachsys.com/csharp/singleton.html

Specifically, see the section with the "Third version"

I would read further down and use his suggestion for how to implement the singleton to see how to implement what you are trying to do.

Why dou you check for "container == null" the first time? I think you should lock first and then check for container being null. All sort of dodgy stuff may happen between the first if and the return in other threads.

Double check with lock is used inside the .NET Framework's code, for singletons (see System.Web.Profile.ProfileManager for example).

So I think your implementation is OK.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM