I have the following code in a Windows Phone 7 Silverlight App of mine which is executed before navigating to another page.
Storyboard storyboard = Resources["TurnstileBackwardO开发者_StackOverflowut"] as Storyboard;
Storyboard.SetTarget(storyboard, LayoutRoot);
storyboard.Completed += delegate
{
storyboard.Stop();
Debug.WriteLine("LeavePageStoryboard.Completed");
NavigationService.Navigate(uri);
};
storyboard.Begin();
The Storyboard is in the resources and is reused quite often. As I understand it, whenever the code is executed, a new delegate is added to the Completed event. My question is: do I have to remove that delegate from the Completed event?
Otherwise after some time, there would be many delegates and some of them wouldn't even belong to the current page, because I use the storyboard on other pages as well.
You should be able to tell if this is a problem, because when you navigate you'll see lots of copies of "LeavePageStoryboard.Completed". Unless it's creating a new Storyboard each time, however, I suspect it is a problem. It's easy to fix though:
EventHandler completedHandler = null; // For definite assignment purposes
completedHandler = delegate
{
storyboard.Stop();
Debug.WriteLine("LeavePageStoryboard.Completed");
NavigationService.Navigate(uri);
storyboard.Completed -= completedHandler;
};
storyboard.Completed += completedHandler;
This is a memory leak, and a common one in C#. If you have a long lived object that gets reused often, it's common for event handlers to pile up on it.
There are a couple options:
1) Make your delegate not be anonymous. Create a method to hold its logic, and referenced delegates. Then remove this referenced delegate when you are done with storyboard.
2) Make storyboard not be long lived. One possibility is to make it a DataTemplate instead and instantiate new copies of it. Then you can attach event handlers to it all you want and once garbage collected, they will get garbage collected too.
精彩评论