如何正确使用代表? (以WPF Storyboards为例)

时间:2011-01-15 16:58:42

标签: c# silverlight windows-phone-7 delegates

我在我的Windows Phone 7 Silverlight应用程序中有以下代码,该代码在导航到另一个页面之前执行。

Storyboard storyboard = Resources["TurnstileBackwardOut"] as Storyboard;
Storyboard.SetTarget(storyboard, LayoutRoot);
storyboard.Completed += delegate
    {
        storyboard.Stop();
        Debug.WriteLine("LeavePageStoryboard.Completed");
        NavigationService.Navigate(uri);
    };
storyboard.Begin();

故事板在资源中并且经常被重复使用。据我了解,无论何时执行代码,都会向Completed事件添加新的委托。我的问题是:我是否必须从已完成的事件中删除该委托?

否则一段时间后会有很多代表,其中一些甚至不属于当前页面,因为我也在其他页面上使用故事板。

2 个答案:

答案 0 :(得分:4)

你应该能够判断这是否是一个问题,因为当你导航时,你会看到很多“LeavePageStoryboard.Completed”的副本。但是,除非它每次创建一个新的故事板,否则我怀疑 是一个问题。虽然很容易解决:

EventHandler completedHandler = null; // For definite assignment purposes
completedHandler = delegate
{
    storyboard.Stop();
    Debug.WriteLine("LeavePageStoryboard.Completed");
    NavigationService.Navigate(uri);
    storyboard.Completed -= completedHandler;
};
storyboard.Completed += completedHandler;

答案 1 :(得分:2)

这是内存泄漏,也是C#中常见的内存泄漏。如果你有一个长期存在的对象经常被重用,那么事件处理程序就会很常见。

有几种选择:

1)让你的代表不是匿名的。创建一个方法来保存其逻辑,并引用委托。完成故事板后,删除此引用的委托。

2)让故事板不长久。一种可能性是使其成为DataTemplate并实例化它的新副本。然后你可以随意附加事件处理程序,一旦收集垃圾,他们也会收集垃圾。