0

Most implementations i've seen containing unmanaged resources end within a method's scope. I'm looking for ways to hold such a resource indefinitely and dispose it as the program stops running. An example of a resource which would quite possibly need to be used this way is CancellationTokenSource.Dispose().

One example would be to use a Destructor: Pass the resources in as dependencies and dispose them at container's last usage. This is feasible in, for instance, Windows Presentation Foundation programs (where the structure has been laid out like this by default) but rewriting the dependency construction for every new unmanaged resource is tiring. As the program scales, so does the distance traveled by the dependency.

A solution could be, to make every class where it's needed, disposable but isn't there a performance cost to liberal use of destructors?

My question to you: creative / uncommon ways of writing this specification. If you have learned the pros and cons of presented methods, please do weigh in anyway!

here's an example WPF program's App.xaml.cs

public partial class App : Application
{
    UnmanagedDependency unmanagedDependency = new UnmanagedDependency();

    public App()
    {
        MainWindow = new MainWindow (unmanagedDependency); //rewrite the constructor of MainWindow
        MainWindow.Show();
    }

    ~App() //destructor method; called when the object is no longer referenced
    {
        unmanagedDependency.Dispose();
    }
}

Afterword: to clarify, my example type UnmanagedDependency is not a wrapper class.

Samuel Jenks
  • 1,137
  • 4
  • 21
  • 34
  • 3
    You are getting this quite wrong, calling Dispose() in a finalizer is a nasty bug that can easily crash your program, randomly. Finalization order is not deterministic. The UnmanagedDependency wrapper class should have a finalizer itself, it already gets called entirely automatically just before your program terminates. The CLR makes one final pass through remaining objects to get them finalized. Whether you store the object reference in a *static* variable to keep it alive forever or as a member of App makes no difference in this specific case. – Hans Passant Apr 22 '17 at 10:03
  • Thanks for pointing that out. UnmanagedDependency could be some wrapper with the sole purpose of destructing the resource. As for nasty bug, Im guessing you mean if I assume that I dispose only once due to order of events when in fact it could have disposed twice due to the random order of finalization. – Samuel Jenks Apr 22 '17 at 11:41
  • 2
    You need to implement finalizer only if your class _directly_ owns unmanaged resource. And in that finalizer all you should do is release those unmanaged resources. You do not own any direct unmanaged resources so you do not need finalizer at all. – Evk Apr 22 '17 at 14:42
  • By directly own do you mean as a class field / property? I dont see the underlying issue. Also why did you delete your answer? – Samuel Jenks Apr 22 '17 at 22:36
  • 1
    @SJ owns means it is allocated and or deallocated likely by the `System.Runtime.InteropServices.Marshal` class or by a P/Invoke call. However if you want a good guide on the right way to deal with unmanaged resources read the article "[IDisposable: What Your Mother Never Told You About Resource Deallocation](https://www.codeproject.com/Articles/29534/IDisposable-What-Your-Mother-Never-Told-You-About)" by Stephen Cleary – Scott Chamberlain Apr 23 '17 at 00:55
  • However, in summary of the article, to solve your problem the resource you you need released before the program is shut down should be represented by a class that derives from `SafeHandle` that is held in a static variable. When the program shuts down the safe handle is cleaned up and the resource is released. – Scott Chamberlain Apr 23 '17 at 01:01
  • Directly own means this same class created this unmanaged resource, usually with some pinvoke call. CancellationTokenSource is not unmanaged resource. UnmanagedDependency is not unmanaged resource (at most it is a wrapper around unmanaged resource). All wrappers will have their own destructors and will be finalized on shutdown without you doing anything. Calling dispose of anything in finalizer is always bad idea. – Evk Apr 23 '17 at 02:52

0 Answers0