Cleaning up resouces in a WPF application
-
Hi, I've got a few classes that implement IDisposable to clean up their resources. In a windows forms app, I would create the objects in the forms constructor and dispose of the objects in the overridden dispose method. In WPF, the Window class doesn't implement IDisposeable. Where should I dispose of these objects? I'm quite new to WPF, so maybe I'm just missing something obvious. Can anyone help.
Simon
-
Hi, I've got a few classes that implement IDisposable to clean up their resources. In a windows forms app, I would create the objects in the forms constructor and dispose of the objects in the overridden dispose method. In WPF, the Window class doesn't implement IDisposeable. Where should I dispose of these objects? I'm quite new to WPF, so maybe I'm just missing something obvious. Can anyone help.
Simon
The WPF Window class doesn't implement IDisposable, because it doesn't have anything to dispose. You can create your own Window class (say MyWindow) that derives from Window and implements IDisposable. Then either you can explicitly call Dispose when you are done with your Window, or you can simply let the finalizer call it for you. Check this[^] and this[^] out, for more info on how to implement IDisposable properly.
Take care, Tom ----------------------------------------------- Check out my blog at http://tjoe.wordpress.com
-
The WPF Window class doesn't implement IDisposable, because it doesn't have anything to dispose. You can create your own Window class (say MyWindow) that derives from Window and implements IDisposable. Then either you can explicitly call Dispose when you are done with your Window, or you can simply let the finalizer call it for you. Check this[^] and this[^] out, for more info on how to implement IDisposable properly.
Take care, Tom ----------------------------------------------- Check out my blog at http://tjoe.wordpress.com
The problem won't be solved by implementing the dispose pattern on the window, I will still be left with a window class that doesn't get disposed as there is nowwhere to call dispose on the Window from. In WPF the entry point is auto generated and looks like this:
/// /// Application Entry Point. /// [System.STAThreadAttribute()] [System.Diagnostics.DebuggerNonUserCodeAttribute()] public static void Main() { WpfApplication1.App app = new WpfApplication1.App(); app.InitializeComponent(); app.Run(); }
(No window class anywhere), and the app.xml file looks like this<Application x:Class="WpfApplication1.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="Window1.xaml"> <Application.Resources> </Application.Resources> </Application>
I don't have control over the creation of the window class, and it won't get disposed of. I tried it, and all that happens is the finaliser gets triggered when the app is closed. What I've done for now is to manually implement the app entry point so I have control over the window creation:public static void Main() { WpfApplication1.App app = new WpfApplication1.App(); using (Window1 mainWindow = new Window1()) { app.Run(mainWindow ); } }
But this doesn't quite feel like the 'WPF way'. I have no app.xaml file. Is there a way of doing this without manually implementing the the app entry point, or is this how it should be done? It's a minor point really, It works fine the way I've done it, just I wondered if there's a proper way of doing it.Simon
-
The problem won't be solved by implementing the dispose pattern on the window, I will still be left with a window class that doesn't get disposed as there is nowwhere to call dispose on the Window from. In WPF the entry point is auto generated and looks like this:
/// /// Application Entry Point. /// [System.STAThreadAttribute()] [System.Diagnostics.DebuggerNonUserCodeAttribute()] public static void Main() { WpfApplication1.App app = new WpfApplication1.App(); app.InitializeComponent(); app.Run(); }
(No window class anywhere), and the app.xml file looks like this<Application x:Class="WpfApplication1.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="Window1.xaml"> <Application.Resources> </Application.Resources> </Application>
I don't have control over the creation of the window class, and it won't get disposed of. I tried it, and all that happens is the finaliser gets triggered when the app is closed. What I've done for now is to manually implement the app entry point so I have control over the window creation:public static void Main() { WpfApplication1.App app = new WpfApplication1.App(); using (Window1 mainWindow = new Window1()) { app.Run(mainWindow ); } }
But this doesn't quite feel like the 'WPF way'. I have no app.xaml file. Is there a way of doing this without manually implementing the the app entry point, or is this how it should be done? It's a minor point really, It works fine the way I've done it, just I wondered if there's a proper way of doing it.Simon
Following the proper implementation of IDisposable, the finalizer should call the Dispose method for you. So if your application is shutting down, and the finalizer is called on the Window, then Dispose should be called. Are you saying that Dispose is not being called in this scenario?
Take care, Tom ----------------------------------------------- Check out my blog at http://tjoe.wordpress.com
-
Following the proper implementation of IDisposable, the finalizer should call the Dispose method for you. So if your application is shutting down, and the finalizer is called on the Window, then Dispose should be called. Are you saying that Dispose is not being called in this scenario?
Take care, Tom ----------------------------------------------- Check out my blog at http://tjoe.wordpress.com
Sorry, thats not what I meant, I'm not very good at explaining. Yes the finalizer is getting called, and yes that triggers the dispose method, but following the pattern, it calls the dispose method and passes false, which means it doesn't clean up managed resources, instead they are left for their own finalizers to be triggered to clean them up, and so on, which means my whole stack of objects are all left waiting for their finalisers to clean them up which is a bit messy, which is what I meant when I said "it won't get disposed of...all that happens is the finaliser gets triggered." Also, finalizers aren't guranteed to be called. I think the way I've done it is the best solution, I get deterministic clean up, and no worries about relying on the finaliser. Thanks for helping.
Simon