2012-09-07 36 views
1

我有一些庫工具使事情變得更簡單。如何讓這個c#屬性線程安全?

 public static RequestUow Uow 
     { 
      get { return ContextItemsHelper.Get<RequestUow>("Uow"); } 
      set { ContextItemsHelper.Set<RequestUow>("Uow", value); } 
     } 

而且在ContextItemsHelper

public static T Get<T>(string key) 
    { 
     Guard.NullOrEmpty(key, "key"); 

     object obj = Items[key]; 

     return obj.IsNotNull() ? (T)obj : default(T); 
    } 

    static IDictionary Items { get { return HttpContextHelper.Current.Items; } } 

這工作得很好,但我現在要檢查屬性UOW爲null,如果設置一個新的RequestUow並返回。

我看過的例子涉及設置自己的成員變量,但是我想知道這是否可能是線程安全的。

任何人有任何建議或解決方案提供?

+0

你還沒有真正提供足夠的代碼來告訴你如何使這個「線程安全」。首先,如果'ContextItemsHelper'是公共的,那麼你不能使你的'Uow'屬性是線程安全的,因爲你不知道其他線程可能在用ContextItemsHelper來做什麼。你可以嘗試使'ContextItemsHelper.Get'線程安全;但如果其他代碼使用'ContextItemsHelper.Items'屬性,則會出現同樣的問題。 –

回答

3

製作Items a ConcurrentDictionary並使用它的AddOrUpdate方法。由於集合本身是線程安全的,因此您不必關心它。

這也將是更好,如果改變了你Get到這樣的事情:

public static T Get<T>(string key) 
{ 
    Guard.NullOrEmpty(key, "key"); 
    return Items.GetOrAdd(key, (key) => default(T)); 
} 

這樣的默認值是在第一次嘗試添加和剛剛返回,如果他們再次調用。

0

只要字典不發生變異(例如無更新),訪問它是沒有任何額外的措施(*)完全線程。

請注意,如果包含的項目本身不是線程安全的,則它無法爲字典提供線程安全的getter/setter。最安全的選擇是在字典中使用不可變項目;如果您的RequestUow對象是可變的,那麼您需要使它們(以及可能使用此字典檢索的其他所有內容)都是線程安全的。

*:請參閱例如this PDF以獲取有關.NET中線程安全集合的信息。第18頁闡明瞭只讀訪問不需要額外測量線程安全性。