Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Removed element still listens to events

Posted on 2011-09-19
8
487 Views
Last Modified: 2013-11-12
Hello there

I got a canvas on what I add some UIElements like this:

private void AddChild(UIElement child, Canvas parent)
{
    // first I remove all the other children
    parent.Children.Clear();

    // then I add the new one
    parent.Children.Add(child);
}

Open in new window


I add my new field on this canvas like this:

private void AddField()
{
    AddChild(new FieldView(), MainCanvas);
}

Open in new window


So I have no other reference to that FieldView, but on the canvas.

This FieldView listens to some events and shows some MessageBoxes. Now, when I add a new FieldView on the MainCanvas, the only reference of the old one should be removed (if I understand this parent.Children.Clear() right).

But it seems like it's not really collected by the GarbageCollector, because now, I always get 2 MessageBoxes on these events (if I add a new field again, I get 3 MessageBoxes and so on).

Can anyone of you tell me, why the old FieldViews aren't removed? Is it just because they still listen to those events or doesn't parent.Children.Clear() really remove them?

Thank you for your help!
0
Comment
Question by:innovasoft
8 Comments
 
LVL 8

Expert Comment

by:jagrut_patel
ID: 36564907
Is the event that FieldView listens to static?
0
 
LVL 3

Expert Comment

by:smickle
ID: 36565191
If you are wiring up the event handler in code, you may have to "unwire" the event handler first. Example:
 
var someElement = whatever;

// unwire event handler if there is one
someElement.SomeEvent -= this.someEventHandler;

// wire event handler
someElement.SomeEvent += this.someEventHandler;

Open in new window


Not sure of your situation, but if you are using any IoC or dependency injection type stuff, then you'll need to be sure your Views and FieldView things are configured with the appropriate lifetime for the containers, so instances of certain controls don't "hang around" after you think they are dead. If you are not using anything fancy like that, then disregard this comment :)

Hope this helps you narrow down the issue.

-Steve
0
 

Expert Comment

by:somanadha
ID: 36566345
You are newing up your FieldView class and adding without cleaning the listeners from the previous FieldView.

That means the event to which the FieldView registered holding the instance of your old FieldView object.

So the GC can't release your FieldView object as they are registered to your event, even though the FieldView is removed from the Canvas.

I don't your code but this is what you could try

before adding a FieldView to the event for call back, clear the event and add the new FieldView object for listening
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 1

Author Comment

by:innovasoft
ID: 36566945
thank you all for your answers.

I see now, that the object still exists, because it's registered to the event. So I have to unwire them, when I remove the Control.

unfortunately, the way, smickle wrote, doesn't work, because it only unwires the listeners of the new class before it re-registers them again.

So, I had the idea to write a dispose-method where all the events will be deregistered. The problem is, when I replace the

parent.Children.Clear();

Open in new window


with

for (int i = parent.Children.Count - 1; i >= 0; i--)
{
    UIElement el = parent.Children[i];

    if (el is IDisposable)
        ((IDisposable)el).Dispose();

    parent.Children.Remove(el);
}

Open in new window


it takes hours to remove the field. Is there a nicer way? Maybe I should do this with parallel tasks?
0
 
LVL 1

Author Comment

by:innovasoft
ID: 36566956
by the way:

@jagrut: no, the events aren't static

@smickle: no, I don't use any dependency injection stuff
0
 
LVL 3

Expert Comment

by:smickle
ID: 36570777
For your Dispose idea, you may have to just unwire the event in your for loop, if it's possible in scope of this for loop. If the event handler is the only thing that is "holding on" to the instance, then GC should cleanup.

I've had issues before that were similar, but mine involved having to explicitly setting the .Content property of my UIElement to null and unwiring event handlers. But that was SL3 stuff. If you are in Silverlight, then there's a known issue, a memory leak, that is kinda sorta related to all of this. It is being fixed in SL5. The known issue is only in SL and not WPF. So if you are in WPF, then you can rule that out.

Here is info on the known bug in SL that causes memory leaks:
https://connect.microsoft.com/VisualStudio/feedback/details/632838/sl-gc-stress-test-memory-leak

0
 
LVL 1

Accepted Solution

by:
innovasoft earned 0 total points
ID: 37043790
actually, I couldn't really fix this. So I just loop through all the children now and dispose them seperately. In the dispose-method, I deregister all the events.

Not nice, but it works.
0
 
LVL 1

Author Closing Comment

by:innovasoft
ID: 37068277
didn't solve the problem
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article describes how to add a user-defined command button to the Windows 7 Explorer toolbar.  In the previous article (http://www.experts-exchange.com/A_2172.html), we saw how to put the Delete button back there where it belongs.  "Delete" is …
If you have ever found yourself doing a repetitive action with the mouse and keyboard, and if you have even a little programming experience, there is a good chance that you can use a text editor to whip together a sort of macro to automate the proce…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

856 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question