views:

61

answers:

2

We have a serial port which is connected to hundreds of physical devices on the same wire. We have protocols like Modbus and Hart to handle the request and response between the application and devices. The question is related to managing the reference count of the channel. When no device is using the channel, the channel should be closed.

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


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

}

For each device connected, we create a object for the device like

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

When the device disconnect,

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

I am not convinced by the reference count model. Are there any better way to handle this problem in .NET World?

+3  A: 

You could consider making Attach return a type implementing IDisposable. That would expose the usable port members, but they'd internally delegate back to the original object (which wouldn't publicly expose anything other than Attach); calling Attach would increase the reference count; disposing of the returned value would decrement it. You'd then be able to do:

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

One oddity to bear in mind is that you start off with a reference count of 0 - but without the port being closed. Should you perhaps only open it on the first Attach call?

Jon Skeet
@Jon, Thanks for answer. Is using block scope make sense for accessing real time devices with milli-seconds interval? Is it not burden to garbage collector?
Gopalakrishnan Subramani
@Gopalakrishnan: The GC can collect an awful lot of objects in a millisecond :) How frequently are you going to attach to the devices? I would have expected a normal use case of attaching to a device, performing a fairly large chunk of work and then detaching. If you're hoping to attach millions of times a second then it *could* cause a GC issue - but it's important to be aware that .NET *isn't* a real-time platform to start with. If your app can't cope with occasional short pauses, you may well have problems.
Jon Skeet
+2  A: 

As mentioned in Jon Skeet's answer you ought to use the Disposable pattern, but, as you seem to be using this class in parallel environments, your increments (++) and decrements (--) need to be atomic, using Interlocked.Increment and .Decrement.

In fact you may need an object to lock() on so you can increment and open the device when the count is 1 (a second Attach at the same moment could try to open the device again) and decrement and then close the device when the count is 0.

Mark Hurd