当没有显式调用观察者上的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消失(在您的应用程序中可能永远不会)。
如果仅对自己的对象使用WhenAny(例如this.WhenAny
,everyever,everyever),则将避免这些情况中的绝大多数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));
});
}
为使此工作有效,这是必须满足的条件:
ISupportsActivation
(超级简单)WhenActivated
。看起来像那样,但事实并非如此。只要记住两件事:
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句