2014-04-19 50 views
1

我創建這樣一個對象:互斥對象創建

 if (_cleaner == null) 
     { 
      _creation.WaitOne(); 
      try 
      { 
       if (_cleaner == null) 
       { 
        //create object 
       } 
      } 
      finally 
      { 
       _creation.ReleaseMutex(); 
      } 
     } 

我之所以做了仔細檢查,是因爲兩個線程可以同時來創建對象,然後我需要明明只有一個創建一個東西。有沒有更好的方法來做到這一點? 所以我不必檢查對象的存在兩次?

+0

這應該沒問題。這是樂觀悲觀的做法 –

+1

爲什麼使用Mutex?你需要這個進行跨進程同步嗎? – argaz

+0

並不重要,你可以使用鎖定,但性能會是相同的 – Windys

回答

3

您可能需要使用Lazy<T>,它更清晰的語法和少error-prone than double check locking

它可以幫助你創建它,只有當被第一次訪問(lazy initialization)一次初始化的對象,我認爲語法是相當不言自明的,一些使用的實例是在this MSDN article,我舉的例子:

class Customer 
{ 
    private Lazy<Orders> _orders; 
    public string CustomerID {get; private set;} 
    public Customer(string id) 
    { 
     CustomerID = id; 
     _orders = new Lazy<Orders>(() => 
     { 
      // You can specify any additonal 
      // initialization steps here. 
      return new Orders(this.CustomerID); 
     }); 
    } 

    public Orders MyOrders 
    { 
     get 
     { 
      // Orders is created on first access here. 
      return _orders.Value; 
     } 
    } 
} 
+0

我不知道如果這是線程安全的,我應該使用什麼ThreadSafetyMode(http://msdn.microsoft.com/en-us/library/system.threading.lazythreadsafetymode(v=vs.110).aspx)以及如何開銷會影響性能? – Windys

+0

您可以使用默認值(不會將ThreadSafetyMode傳遞給Lazy 的構造函數),它是ThreadSafetyMode.ExecutionAndPublication且是線程安全的。 http://msdn.microsoft.com/en-us/library/dd642329%28v=vs.110%29.aspx – argaz

0

也許使用一個有生命期管理器來幫助管理你的對象的框架(例如Unity)? 順便說一句,Unity做了很多。

Unity - Lifetime manager

+0

這更像是單身模式,不是嗎? – Windys

+0

Unity可讓您在處理每個對象上的終生管理者時解析對象(它也爲您提供了di和其他選項的選項)。 解析函數是線程安全的,所以基本上可以定義類A將生成單例對象,而類B將生成HTTPContext對象。您也可以通過實施簡單的界面來構建自己的定製生命期管理器。 用法很簡單 - 您可以按類型解析對象。 –