2

When using unmanaged resources, what is the best practise for passing them to other objects? I understand it should be the responsibility of the class which creates the unmanaged resource to dispose of it, but does the resource persist if I pass it to a constructor, which then places it in a private field for use throughout the object's life.

For example, consider the following scenario:

public class Source
{
     public static void Main(string[] args)
     {
          using (MyUnmanagedResource r = new MyUnmanagedResource())
          {
               Helper helper = new Helper(r);
               helper.M1();

               Helper helper2 = new Helper();
               helper2.M2(r);
          }
     }
}
public class Helper
{
     private MyUnmanagedResource resource;

     public Helper(){}
     public Helper(MyUnmanagedResource r)
     {
       resource = r;
     }

     public void M1()
     {
        Changer c = new Changer(resource);
        c.M1();

     }
     public void M2(MyUnmanagedResource re)
     {
        Changer c = new Changer();
        c.M2(re);
     }
}
public class Changer
{
     private MyUnmanagedResource resource;

     public Changer(){}
     public Changer(MyUnmanagedResource r)
     {
       resource = r;
     }

     public void M1()
     {
        resource.DoThing();
     }
     public void M2(MyUnmanagedResource re)
     {
        re.DoThing2();
     }
}

In this situation, which is the best practise? Passing it in to the private variable for use later is certainly easier to write, but does this cause issues with disposing of the resource? With just one method in this example, the latter seems better, but when you have 10-15 methods that use the resource, and other classes being invoked that need the resource too, it can get very messy.

I've had issues with memory leaks in the past, and i'm not sure if its the way I handle unmanaged resources. I changed the unmanaged resource to be passed by argument, but it lead to it being an argument in around 50 methods, which seemed a pain.

plusheen
  • 1,128
  • 1
  • 8
  • 23
  • 2
    sounds like `Helper` needs to implement `IDisposeable` and it to dispose `r` instead of your using. – Daniel A. White Jun 03 '16 at 15:43
  • Is it not best to let the using dispose of it, as it's the object that created the resource? In addition - I have cases where the object is passed 3 or 4 classes deep. I'm not sure how this would still apply – plusheen Jun 03 '16 at 15:49
  • if you are going to hand off control of it to another object, you might not want to. – Daniel A. White Jun 03 '16 at 15:51
  • Thanks for the replies @DanielA.White . I edited the original code to add another level of classes that use the managed resource. Would you suggest having a dispose at every class level in which the unmanaged resource exists as a private field? – plusheen Jun 03 '16 at 15:59
  • Explicit disposal gets to be *very* impractical once you start handing out references to other code that is beyond your control. So just don't and leave it up to the garbage collector, use GC.AddMemoryPressure() to help it. You **must** implement a finalizer to ensure that cleanup is always taken care of. With the additional note that you should never write one yourself but leave it up to one of the SafeHandle classes. – Hans Passant Jun 03 '16 at 16:09
  • Not gonna lie, I've never actually implemented a finalizer, nor do I understand the concept all that well. I will do a little reading up. For what it's worth, its only my code that is passed the reference, so I have full control over it. – plusheen Jun 03 '16 at 16:19

0 Answers0