Время жизни ReactiveUI ObservableForProperty

Мне любопытно время жизни ObservableForProperty жизни, когда явно не вызывается Dispose на наблюдателя. Мне действительно все равно в этом сценарии о получении подписок слишком долго и т. д.

в традиционном .NET, если у вас есть события, если вы не отписались, это может потенциально привести к утечкам памяти из-за того, что ваше время жизни объекта связано с событием. например, как предложено в http://msdn.microsoft.com/en-us/magazine/cc163316.aspx :

события также могут быть сильными корневыми ссылками и как таковые могут способствовать сильному ссылочному пути и, таким образом, влиять на время жизни объекта. Обычные события в common language runtime (CLR) 2.0 являются двунаправленными сильными ссылками между источником событий и прослушивателем и как таковые могут поддерживать объект (источник или прослушиватель), который в противном случае должен быть уже мертв.

просмотр базы кода ReactiveUI при встрече с Объект INotifyPropertyChanged, я заметил, что вы используете fromeventpattern, подписываясь на событие INotifyPropertyChange.

позволяет ли использование ObservableForProperty обойти эту проблему сохранения объекта дольше, создав сильный ссылочный путь?

спасибо, Гленн!--1-->

1 ответов


вы правы, использование WhenAny / ObservableForProperty неправильно может привести к утечке памяти приложения, если вы не будете осторожны. Рассмотрим следующий код:

public ItemInAListBoxViewModel(MainWindowViewModel mainWindow)
{
    this.window = mainWindow;

    // Reset the "selected" when the user minimizes
    this.WhenAnyValue(x => x.window.IsMinimized)
        .Where(x => x == true)
        .Subscribe(x => this.IsSelected = false);
}

поскольку мы метод whenany бы через объект, чей срок жизни составляет больше чем у нас (т. е. элемент списка против окна), мы держим элементы списка навсегда, пока окно не исчезнет (что может никогда не быть в вашем приложении).

вы будете избегать подавляющего большинства из этих случаев, если вы только WhenAny на свой собственный объект (т. е. всегда this.WhenAny, не someObject.WhenAny).

специальное примечание о свойствах зависимостей

несмотря ни на что, ты есть чтобы избавиться от любого WhenAny, который проходит через DependencyProperty, иначе вы утечка. Потому Что Окна.

дерьмо, что мне теперь делать?

новая функция была добавлена в ReactiveUI для обработки сценария, где вы do хотите это сделать , называется "активация". Вы можете найти более подробную информацию по адресу:

теперь мы можем определить область "вещей, которые должны быть активны только на экране", которая исчезнет сразу после того, как представление и его ViewModel будут удалены с экрана (т. е. удалены из визуального дерева в WPF).

public ItemInAListBoxViewModel(MainWindowViewModel mainWindow)
{
    this.window = mainWindow;

    Activator = new ViewModelActivator();

    // This gets called every time the View for this VM gets put on screen
    this.WhenActivated(d => {
        // The 'd' is for "Dispose this when you're Deactivated"
        d(this.WhenAnyValue(x => x.window.IsMinimized)
            .Where(x => x == true)
            .Subscribe(x => this.IsSelected = false));
    });
}

для этого, чтобы работать, вот что должно быть так:

  1. ваш VieWModel должен реализовать ISupportsActivation (супер легкий)
  2. представление, связанное с вашей ViewModel необходимо вызвать WhenActivated тоже.

это звучит очень жесткой!

это выглядит так, но это совершенно не так. Просто запомните две вещи:--7-->

  1. не WhenAny через объекты, которые остаются вокруг навсегда, если вы и остаться навсегда
  2. если у вас есть to, используйте WhenActivated.