Шаблон для управления счетчиком ссылок и жизнью объекта - PullRequest
5 голосов
/ 18 марта 2010

У нас есть последовательный порт, который подключен к сотням физических устройств по одному проводу. У нас есть протоколы, такие как Modbus и Hart для обработки запросов и ответов между приложением и устройствами. Вопрос связан с управлением счетчиком ссылок канала. Когда ни одно устройство не использует канал, канал должен быть закрыт.

public class SerialPortChannel
{ 
   int refCount = 0;
   public void AddReference()
   {
      refCount++;
   }   


   public void ReleaseReference()
   {
      refCount--;
      if (refCount <= 0)
           this.ReleasePort(); //This close the serial port
   }   

}

Для каждого подключенного устройства мы создаем объект для устройства, например

  device = new Device();
  device.Attach(channel);    //this calls channel.AddReference()

При отключении устройства

  device.Detach(channel); //this calls channel.ReleaseReference()

Меня не убеждает модель подсчета ссылок. Есть ли лучший способ справиться с этой проблемой в .NET World?

Ответы [ 2 ]

5 голосов
/ 18 марта 2010

Вы могли бы сделать так, чтобы Attach возвращал тип, реализующий IDisposable. Это открыло бы доступные для использования члены порта, но они внутренне делегировали бы обратно к исходному объекту (который публично не предоставит ничего, кроме Attach); вызов Attach увеличит количество ссылок; избавление от возвращенного значения уменьшило бы его. Тогда вы сможете сделать:

using (Foo foo = device.Attach(channel))
{
    ...
}

Одна странность, которую нужно иметь в виду, заключается в том, что вы начинаете со счетчика ссылок 0, но без закрытия порта. Возможно, вам следует открыть его только при первом Attach звонке?

2 голосов
/ 18 марта 2010

Как упоминалось в ответе Джона Скита, вы должны использовать шаблон Disposable, но, поскольку вы, похоже, используете этот класс в параллельных средах, ваши приращения (++) и декременты (--) должны быть атомарными, используя Interlocked.Increment и .Decrement.

На самом деле вам может понадобиться объект на lock(), чтобы вы могли увеличивать и открывать устройство, когда счетчик равен 1 (секунда Attach в тот же момент может попытаться снова открыть устройство) и уменьшить его. и затем закройте устройство, когда счетчик 0.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...