2014-01-25 45 views
0

我是新约的反应,但想法把我的好奇心,所以我做了一些有点反应变量,但我不知道这是否是最好的初步实践,然后我就会把这个线程。使属性线程安全c#信号量或锁?

这里的类:

公共类RxVar:的IObservable {

T _value; 
    public T Value 
    { 

     get{ 
      return _value; 
     } 
     set{ 
      if (!_value.Equals(value)) 
      { 
       onChange(_value); 
       _value = value; 
      } 
     } 

    } 


    event onValChange onChange = delegate { }; 
    delegate void onValChange(T val); 

    IObservable<T> _observable; 
    public RxVar() { 

     _observable = Observable.FromEvent<onValChange,T>(ev => onChange += ev, ev => onChange -= ev); 
    } 



    public IDisposable Subscribe(IObserver<T> observer) 
    { 
     return _observable.Subscribe(p=>observer.OnNext(p)); 
    } 
} 

信号灯例如

 _semaphoreSlim.WaitOne(); 
     if (!_value.Equals(value)) 
     { 
      onChange(_value); 
      _value = value; 
     } 
     _semaphoreSlim.release(); 

好吧我想让这个线程安全,并且我对死锁感到恐慌,所以 使用lock或semaphone会更好,还是因为不需要反应性本身?

谢谢。 :)

回答

3

我推荐一个锁,而不是一个信号。信号量只是这种情况下的错误工具。

考虑与暴露的实际价值“回归_value”指的是,吸气返回后,也客户端代码将能够修改对象中的数据。所以问题是,如果你在公开参考资料之后会如何避免竞争条件?

答案是不公开的参考。给出对象/数据的深层拷贝,而不是原始对象本身。

关于死锁:在所有的,如果你知道你在做什么,你不应该害怕。如果你不这样做,你会发现永远不会有死锁,因为在每次运行中,条件可能会有所不同,甚至在经过多次成功的测试后,可能会导致死锁和调试,这将是一件困难的事情。

死锁只能通过学习才能避免,而不是通过“编程时不知道”的方式。

小片段与锁:

类的实例字段(你需要这个,如果_value可以为空,否则,你可以锁定_value本身):

private object _valueLock = new Int(0); 

在你的方法:

lock(_valueLock) 
{ 
    if (_value != value) // this or deep equality 
    { 
     _value = value; 
     onChange(this, _value); // for complex Observer-Observable scenarios it's better specifying the observed object 
    } 
} 
+0

真的谢谢你,反正我不明白为什么semaphone不能做的工作:) – LXG

+1

信号量是最适合于其他场景,如[生产者/消费者(http://en.wikipedia.org/wiki/监制%E2 %80%93consumer_problem)或[读者/作者](http://en.wikipedia.org/wiki/Readers-writers_problem)。这种情况是一个简单的[互斥](http://en.wikipedia.org/wiki/Mutex),因此可能有更清晰的代码和更有效的实现。 – pid