Рекомендации по блокировке (или вводу / завершению) в C#

#c# #multithreading #locking

#c# #многопоточность #блокировка

Вопрос:

У меня есть объект измерительного прибора:

 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();
    }
  }
}
  

Я читал, что лучше всего блокировать частные объекты, но я не знаю, как это сделать, все еще позволяя MeasuringInstrument получать / устанавливать на устройстве. Есть предложения?

Большое спасибо,
Кен

Комментарии:

1. для будущих поколений: рекомендации по управлению потоками msdn.microsoft.com/en-us/library/1c9txz50 (v =против110).aspx

Ответ №1:

если ваш instrument используется несколькими devices , лучше всего установить lock в вашем instrument классе. таким образом, первое решение работает лучше.

но лучше создать новый объект блокировки и использовать его в instrument классе.

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

Комментарии:

1. @frazin. Я согласен, но лучший ответ включал бы, почему его лучше

Ответ №2:

обычным шаблоном является создание собственного private object только для блокировки в случае, когда очевидный выбор может быть предоставлен за пределами класса, например:

 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();
        }
    }
}
  

Кроме того, я подозреваю, что вам нужна только одна из этих двух блокировок (либо та, что в DoMeasuring , либо та, что в Measure ), хотя это зависит от недостающих битов.

Комментарии:

1. Вторая блокировка в устройстве не требуется.

2. hii.. Я новичок в обработке потоков и блокировке… Используйте блокировку для частных объектов.. все в порядке. Но, пожалуйста, скажите мне, что на самом деле делает «блокировка». Я имею в виду, что если существует 10 объектов класса Instrument, то у каждого объекта будет своя копия Measure (). Итак, какова цель блокировки?