2009-01-26 89 views
2

我在HttpApplicationState对象上有一个扩展方法,用于让我的IoC容器脱离应用程序。如果该容器不存在,该代码也会创建该容器。ASP.NET线程 - 双重检查锁定

我有2个问题:

  1. 是我的代码实际上是线程安全的,因为我想让它是
  2. 这被认为是最好的做法来处理应用程序的状态

守则如下:

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; 
} 
+0

除此之外,由于我从Unity转移到StructureMap和SM中,我将这个完整的问题作为一个静态类公开,因此我从不需要担心它不存在。 – 2009-02-15 23:43:50

回答

3

你需要把

var container = application[GlobalContainerKey] as IUnityContainer; 

在锁定为好,否则许多线程可能会在序列中的新的容器。

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; 
} 
+0

你是对的,我的意思是在第二个if语句之前就在那里。 – 2009-01-26 19:35:55

1

从技术上讲,根据EMCA规定,这将不起作用灰。乔恩斯基特进入这在他的C#FAQ:

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

具体请参见与“三版”

我会进一步下跌阅读和使用他的建议对如何实现单到看看如何实现你正在尝试做的事情。

+0

区别在于我已经与一个单身人士没有试图创建一个新的单身人士。在反对DCL的理由中,阅读第2点是唯一合法的点,但没有详细说明为什么它不起作用,或者“明确的记忆障碍呼叫”将如何确保它。 – 2009-01-26 19:46:11

1

为什么你第一次检查“container == null”?我认为你应该先锁定,然后检查容器为空。各种各样的狡猾的东西可能会发生在第一个if和其他线程的返回之间。

+0

我不想在容器存在后的每一次都锁定应用程序,因为这会在每个页面请求中调用。只需要为初始插入锁定。然而,我的意思是有第二个“container = application [GlobalContainerKey]作为IUnityContainer;”锁定后 – 2009-01-26 19:37:27

1

使用锁的双重检查在.NET Framework的代码中用于单例(请参阅System.Web.Profile.ProfileManager)。

所以我认为你的实现是好的。

相关问题