簡體   English   中英

ReactiveUI ObservableForProperty生存期

[英]ReactiveUI ObservableForProperty lifetime

當沒有顯式調用觀察者上的Dispose時,我對ObservableForProperty生命周期的生命感到好奇。 在這種情況下,我真的不太在意訂閱時間過長等問題。

在傳統的.NET中,如果您有事件,除非您取消訂閱,否則可能會導致內存泄漏,原因是對象的生存期已綁定到該事件。 例如,如http://msdn.microsoft.com/en-us/magazine/cc163316.aspx中所建議:

事件也可以是強根引用,因此可以促成強引用路徑,從而影響對象的生存期。 公共語言運行時(CLR)2.0中的普通事件是事件源與偵聽器之間的雙向強引用,因此可以使對象(源或偵聽器)保持活動狀態,否則該對象應該已經失效。

在遇到INotifyPropertyChanged對象時瀏覽ReactiveUI代碼庫,我注意到您正在使用FromEventPattern訂閱INotifyPropertyChange事件。

通過創建強引用路徑,使用ObservableForProperty是否可以解決使對象保持更長時間活動的問題?

謝謝,格倫

您是正確的,如果使用不當,不正確地使用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通過了一個壽命比我們的壽命更長的對象 (即ListBox項與Window),所以我們將永久持有ListBox項直到Window消失(在您的應用程序中可能永遠不會)。

如果僅對自己的對象使用this.WhenAny ,則將避免絕大多數情況(即始終為this.WhenAny ,從不對someObject.WhenAny )。

有關依賴項屬性的特別說明

無論如何,您必須處置通過DependencyProperty的任何WhenAny,否則就會泄漏。 因為Windows。

廢話,我現在該怎么辦?

ReactiveUI已添加了一個新功能來處理您確實要執行此操作的場景,稱為“激活”。 您可以在以下位置找到更多信息:

現在,我們可以定義“僅在屏幕上才可活動的事物”的范圍,該范圍在將View及其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關聯的View也需要調用WhenActivated

聽起來很難!

看起來像那樣,但事實並非如此。 只要記住兩件事:

  1. 不要通過任何永久存在的物體,除非您永久存在
  2. 如果需要,請使用WhenActivated。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM