C#中锁定(或进入/退出)的最佳实践

5

我有一个测量仪器对象:

public class Instrument
{
  public double Measure() 
  { 
    return 0; 
  }
}

我有一个需要进行一些测量的设备:

public class Device
{
  public Instrument MeasuringInstrument { get; set; }
  public void DoMeasuring()
  {
    var result = this.MeasuringInstrument.Measure();
  }
}

测量仪器一次只能在一个设备上操作,但许多设备可能使用同一仪器。我对线程不太熟悉,据我所知,以下两种解决方案都有缺陷。

public class Instrument
{
  public double Measure() 
  { 
    lock(this)
    {
      return 0; 
    }
  }
}

public class Device
{
  public Instrument MeasuringInstrument { get; set; }
  public void DoMeasuring()
  {
    lock(this.MeasurementInstrument)
    {
      var result = this.MeasuringInstrument.Measure();
    }
  }
}

我了解到最好锁定私有对象,但是我不知道如何在允许对设备进行get/set的同时进行锁定。你有什么建议吗?

非常感谢,
Ken


为了后代:托管线程最佳实践 http://msdn.microsoft.com/zh-cn/library/1c9txz50(v=vs.110).aspx - Brad
2个回答

5

如果您的仪器被多个设备使用,最佳实践是在仪器类中设置锁定。因此,第一种解决方案效果更好。

但最好创建一个新的锁对象,并在仪器类中使用它。

public class Instrument
{
  Object lockKey = new Object();
  public double Measure() 
  { 
    lock(lockKey)
    {
      return 0; 
    }
  }
}

1
@frazin。我同意,但更好的答案应该包括为什么它更好。 - Conrad Frix

3

通常的模式是创建一个私有的对象,用于锁定,在明显的选择可能会暴露在类外部的情况下,例如:

public class Instrument
{
    private object thisLock = new object();

    public double Measure() 
    { 
        lock(this.thisLock)
        {
            return 0; 
        }
    }
}

public class Device
{
    public Instrument MeasuringInstrument { get; set; }
    private object measuringInstrumentLock = new object();

    public void DoMeasuring()
    {
        lock(this.measuringInstrumentLock)
        {
            var result = this.MeasuringInstrument.Measure();
        }
    }
}

另外,我怀疑你只需要这两个锁中的一个(或者是在DoMeasuringMeasure中的一个),但这取决于缺失的部分。


设备中的第二个锁不是必需的。 - Farzin Zaker
嗨,我是新手,在线程和锁方面不熟悉。在私有对象上使用锁是可以的。但请告诉我"lock"实际上是做什么的。我的意思是,如果有10个Instrument类的对象,则每个对象都将有自己的Measure()副本。现在,锁的目的是什么? - himanshu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接