2014-04-19 52 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对象。您也可以通过实施简单的界面来构建自己的定制生命期管理器。 用法很简单 - 您可以按类型解析对象。 –