4

I am using an object that implements IDisposable in my WPF custom control. How can I ensure this object is disposed when the control is GC'ed? There's no Dispose() or any method in Control class that I can override to dispose my object.

Chris
  • 357
  • 4
  • 16

4 Answers4

1

If you are using an object that needs to be disposed of, try using the Application.Shutdown Method to release the resources on shutdown, or try the Unloaded event to release the resources when you remove the control from the visual tree. You may need to use a combination of the two methods.

Try looking at this question to see if it helps

Community
  • 1
  • 1
Mark Hall
  • 53,938
  • 9
  • 94
  • 111
  • This question doesn't really solve the problem. It's not the answer. Why call dispose at Application.Shutdown, when the OS will recapture the memory anyway? If the user is shutting down the app, then memory leaks are no longer a problem, because they are not using the app anymore. Unloaded doesn't get called by Windows.Close(). It seems more like a random function than anything else. Best is likely to create your own Unloaded method, and call that on Window.Close(), though there could be many problems with it. – Michael T Jun 21 '11 at 04:45
1

I think if you follow MVVM design pattern then resources should be held in the model or view model.

Plus, weak event pattern should be used to attach events.

Chris
  • 357
  • 4
  • 16
0

The finalizer should call Dispose if it has not been called already. If you are dealing with a .NET type then you can be assured that it will. The finalizer will get called when the object is GC'd and you'll be ok.

This is typical for controls such as a Picturebox that display a Bitmap. Unless you are swapping out that Bitmap often (in which case you should dispose of it) you can likely get by without being overly cautious.

That said, it comes down to your app and how it works. If you have a lot of objects that implement IDisposable that aren't needed anymore, but may have live references lying around for a relatively long time, then you should be more proactive and create a scheme to ensure these things are cleaned up as deterministically as possible.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • The problem is WPF controls do not have Dispose method. – Chris Jun 21 '11 at 03:31
  • @user775602: Right, because they don't need it, so why is that a problem? – Ed S. Jun 21 '11 at 04:23
  • 1
    The problem is he's adding a non-WPF item to his WPF UserControl. For example, he could have a BackgroundWorker declared in his WPF UserControl. The UserControl does not require dispose, but the BackgroundWorker does. When should he call that? I wrote an answer. – Michael T Jun 21 '11 at 04:25
  • @Michael: Well, he should call it... when he needs to I suppose. This is impossible to answer given the info in the question. Since he wrote the user control it should be simple enough to call Dispose at some point or do it in the Unloaded event (assuming that's a safe thing to do of course). – Ed S. Jun 21 '11 at 04:29
  • 1
    The problem is, the Unloaded event doesn't get called. This has to be one of the most common WPF questions, and it's a very good question, once you realize the problem. And, the question is all over this website, and I think my answer is the best. Here's another example of the very same question: http://stackoverflow.com/questions/1499477/wpf-window-close-not-triggering-usercontrol-unloaded-event – Michael T Jun 21 '11 at 04:39
0

I dealt with this last night. That is, I needed to call dispose on an object in a UserControl. I think you have two options.

I added a instance of BackgroundWorker to the WPF UserControl. That may or may not be a good idea, but whatever. Only one instance of the BackgroundWorker needs to be run per UserControl. So, I initialize the BackgroundWorker as null. When I need to use the BackgroundWorker, I check to see if it's null, and then create a new instance of it, have it do its work. Then, I dispose of it in the worker complete event, and set it back to null.

You can use the WPF Window closing or unload events. Unload doesn't get called on the UserControl, but it does in the Window that holds that UserControl.

WPFWindow Event Close (or Unload, or whatever) calls a custom release function in your UserControl. This custom release function does the work.

So, there's no real good one size fits all solution to your problem. It requires more design and thought to handle features that require dispose, because, in general, WPF doesn't require it. WPF generally only requires you to set items to null. (Does UserControl.Unload get called when you set the UserControl to null? Haven't thought about it before now, but if it does, that would be the correct answer.)

Michael T
  • 1,367
  • 2
  • 16
  • 27