11

I have a member in the WPF code behind that is disposable (meaning it implements the IDisposable interface)

I do not see any Dispose method I can override from UserControl in WPF so I can dispose of the member in my wpf usercontrol

What is the correct way to dispose of a member in a WPF usercontrol?

It's a usercontrol that wraps a private member which implements the IDisposable interface. Thus I need to dispose of that member somewhere. In the tradition winform, the usercontrol had a Dispose method that could be overriden so that in the override I could dispose of the private member. But in the WPF usercontrol, there is no such thing. So I was wondering where can I dispose of the private member in the wpf usercontrol.

My question is not about disposing the usercontrol, but where to dispose one of its private member which implement the IDisposable interface

pdiddy
  • 6,217
  • 10
  • 50
  • 111
  • 1
    Do you actually *need* to call Dispose()? Is this your own WPF control? Does it wrap unmanaged code that needs to be cleaned up? Or does it use a lot of memory and thus requires that you use Dispose() to force the GC to clean up sooner? I've yet to call Dispose() on any of my UserControls, and haven't (yet) seen any memory leaks from them. Can you provide more information here about the UserControl? – Dave Sep 10 '10 at 15:33
  • see my updated answer below -- it *might* do the trick for you so you don't have to add an Unloaded event handler. – Dave Sep 10 '10 at 15:44

3 Answers3

5

You could use the Unloaded event of the UserControl to do your resource cleanup.

MrDosu
  • 3,427
  • 15
  • 18
  • Is this the standard way of doing it ? – pdiddy Sep 10 '10 at 15:20
  • 2
    The standard way would be to eliminate the code behind through something like a MVVM/MVP pattern or the like and deal with the Disposing on a higher level. – MrDosu Sep 10 '10 at 15:33
  • 3
    That will not work. From MSDN documentation: Note that the Unloaded event is not raised after an application begins shutting down. Application shutdown occurs when the condition defined by the ShutdownMode property occurs. If you place cleanup code within a handler for the Unloaded event, such as for a Window or a UserControl, it may not be called as expected. – Mike Post Nov 18 '10 at 22:25
  • 1
    +1 for calling out that Unloaded is unlikely to help here. I've been fighting a similar issue in some legacy code where a UserControl allocates a bunch of stuff in code-behind, but provides no opportunity to clean up after itself when the control goes away. It's unlikely you'd intend to do such cleanup when the element is simply removed from the visual tree rather than being closed for good. +1 also for the right answer here, which is to not do these allocations in the View in the first place, but in the ViewModel. Needless to say my legacy code is not particularly MVVM! – lesscode Jul 11 '13 at 15:23
  • This is not really true. If you need to cleanup unmanaged resources you should implement a finalizer alongside properly implementing the IDisposable pattern. Disposing is primarily used for freeing resources at a deterministic time and not making absolutely sure you dont leak unmanaged things. This case is only about disposing the private member at the time the UserControl 'dies'. – MrDosu Jul 11 '13 at 16:21
  • Quick googling explains it better than i can: http://reedcopsey.com/2009/03/28/idisposable-part-1-releasing-unmanaged-resources/. IDisposable is probably the number 1 pattern i see horribly misused the most. – MrDosu Jul 11 '13 at 16:23
  • @MrDosu: I think you missed the point that Unloaded is fired when the control is removed from the visual tree, not when the control 'dies' (I assume you mean when the control's parent or the app itself is closed). Lots of things can cause the control to be removed from the visual tree (eg. switching tabs, navigating away from a page, changing themes), and if you're tying your Dispose() calls to the Unloaded event you're potentially going to be prematurely freeing resources that may be needed again when the element re-enters the visual tree. – lesscode Jul 12 '13 at 02:59
  • @Wayne This is true, but what else would be the point of disposing resources deterministically unless you want them freed as soon as possible. Trivially you would need to reallocate when the UserControl is later reused and Loaded. I think you are confusiong disposing (free this stuff here at the time i tell you to because i only need it for this set time that i have under my control) with finalization (dont let me leak these resources, i dont care when). – MrDosu Jul 12 '13 at 10:30
  • @MrDosu: With respect, I don't think I'm confusing them at all. No-one brought up finalization and unmanaged resources except for you. The OP wanted to Dispose() a managed IDisposable allocated by a WPF UserControl, but since UserControl itself is not IDisposable, he couldn't find a good way to do it. You suggested the Unloaded event, and a couple of us have pointed out that that's unlikely to work the way one might like or expect. Your first comment here should be considered a more useful and correct answer than the actual answer. – lesscode Jul 12 '13 at 13:57
  • Note that while Unloaded may not be called on application Shutdown, most of the resources you are using do not have to be disposed on program exit, so it's not a big deal (like Direct3D or many other COM objects/native file handles etc.) as tearing down the process will close them anyway. – ghord Sep 22 '14 at 16:14
1

You would do it in the Dispatcher.ShutDownStarted event handler. See this question for details (which in turn refers to this blog post).

Community
  • 1
  • 1
Mike Post
  • 6,355
  • 3
  • 38
  • 48
0

UPDATE

When you call into your private member that implements IDisposable, can you use using? This way, it gets disposed of automatically. I haven't personally done it this way in a UserControl, but it might do the trick. e.g.

using( MyPrivateDisposable mpd = new MyPrivateDisposable) {
    mpd.MethodA();
}

old answer

If you can't call Dispose(), the problem is that your UserControl doesn't inherit from Disposable(). UserControl itself is not derived from it so you have to explicitly make your WPF control inherit from it, i.e.

public class MyControl : UserControl, IDisposable {...}

See the UserControl base types here:

alt text

Once you implement IDisposable, you can call it. But as I wrote in my comment to your question, I think you need to post more information about this class. Ask yourself if you really need to call Dispose() on it... i.e. does your UserControl access handles, or use unmanaged code? If not, I don't see why you would have to call Dispose() on it unless you really wanted the GC to clean it up.

Dave
  • 14,618
  • 13
  • 91
  • 145
  • I understand that usercontrol in wpf doesn't implement IDisposable. But my question is not about disposing of the usercontrol .... – pdiddy Sep 10 '10 at 15:38
  • Ok, it looks like you edited your question again, thanks, I see that you do implement IDisposable. – Dave Sep 10 '10 at 15:39
  • @pdiddy ok, now I understand what you're asking. – Dave Sep 10 '10 at 15:40
  • Thanks for answering. But in my case I don't want to use using for different reason. So I do need to keep a private member and dispose it later on ... – pdiddy Sep 10 '10 at 15:49
  • okie, no problem. As long as you've got a solution to your problem that works, it's all good. :) – Dave Sep 10 '10 at 17:45