ReactiveUI ObservableForProperty生存期

格伦·沃森

当没有显式调用观察者上的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.WhenAnyeveryever,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));
    });
}

为使此工作有效,这是必须满足的条件:

  1. 您的VieWModel需要实现ISupportsActivation(超级简单)
  2. 与ViewModel关联的View也需要调用WhenActivated

听起来很难!

看起来像那样,但事实并非如此。只要记住两件事:

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Cassandra会话生存期

来自分类Dev

StructureMap生存期范围

来自分类Dev

StructureMap生存期范围

来自分类Dev

为什么ReactiveUI的ObservableForProperty的ToProperty导致F#中的FailInit

来自分类Dev

如何指定Option <closure>的生存期?

来自分类Dev

SmtpClient-什么是适当的生存期?

来自分类Dev

JavaScript中匿名对象的生存期

来自分类Dev

ViewModel,消息和生存期

来自分类Dev

循环变量生存期的C ++很奇怪

来自分类Dev

C ++中指针引用的生存期

来自分类Dev

头文件中数组的生存期

来自分类Dev

str类型的生存期/借期问题

来自分类Dev

ViewModel,消息和生存期

来自分类Dev

QuickBlox QBContent生存期或自动删除

来自分类Dev

Laravel文件对象生存期

来自分类Dev

异步函数调用的参数生存期

来自分类Dev

会话生存期未按预期工作

来自分类Dev

使用createUserSession()设置会话生存期

来自分类Dev

ARC中奇怪的对象生存期:如何强制精确的对象生存期?

来自分类Dev

如何指定方法参数的生存期必须比self的生存期长?

来自分类Dev

如何将结构的生存期限制为“父”结构的生存期?

来自分类Dev

<'a,'b:'a>意味着生存期'b必须超过生存期'a吗?

来自分类Dev

如何使用结构和impl的生存期为实现推断合适的生存期?

来自分类Dev

如何指定该方法参数的生存期必须比self的生存期长?

来自分类Dev

为什么函数参数的生存期与函数内部绑定的生存期不同?

来自分类Dev

C中局部变量的范围和生存期

来自分类Dev

浏览器中的Angular应用生存期

来自分类Dev

重用存储是否会开始新对象的生存期?

来自分类Dev

基于范围的for循环的对象生存期问题

Related 相关文章

热门标签

归档