Как правильно использовать делегатов?(используя раскадровки WPF в качестве примера) - PullRequest
0 голосов
/ 15 января 2011

У меня есть следующий код в моем приложении 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 добавляется новый делегат.У меня вопрос: нужно ли удалять этого делегата из события Completed?

Иначе через некоторое время будет много делегатов, и некоторые из них даже не будут принадлежать текущей странице, потому что я используюраскадровка и на других страницах.

Ответы [ 2 ]

4 голосов
/ 15 января 2011

Вы должны быть в состоянии сказать, если это проблема, потому что при навигации вы увидите много копий "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;
2 голосов
/ 15 января 2011

Это утечка памяти, распространенная в C #.Если у вас есть долгоживущий объект, который часто используется повторно, обработчики событий обычно накапливаются на нем.

Есть несколько вариантов:

1) Сделайте так, чтобы ваш делегат не был анонимным.Создайте метод для хранения его логики и ссылки на делегатов.Затем удалите этого делегата по ссылке, когда закончите с раскадровкой.

2) Сделать раскадровку не долгой.Одна из возможностей состоит в том, чтобы вместо этого сделать его DataTemplate и создать его новые копии.Затем вы можете прикрепить к нему обработчики событий, какие захотите, и после сбора мусора они также будут собирать мусор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...