2009-01-26 78 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)。

所以我認爲你的實現是好的。

相關問題