我应该总是处理 observable 的订阅吗? [英] Should I always dispose subscriptions of observables?

查看:35
本文介绍了我应该总是处理 observable 的订阅吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ViewModel 自动超出范围并且没有维护对其他类的引用时,我应该总是处理 observables 吗?

Should I always dispose observables when the ViewModel automatically goes out of scope and no reference to other classes is maintained?

一个小例子:

public class TestViewModel : ReactiveObject
{
    public TestViewModel()
    {
        MyList = new ReactiveList<string>();
        MyList.ChangeTrackingEnabled = true;

        //Do I have to dispose/unsubscribe this?
        MyList.ItemChanged.Subscribe(_ => ...);

        //Or this?
        this.WhenAnyValue(x => x.MyList).Subscribe(_ => ...);
    }

    ReactiveList<string> _myList;
    public ReactiveList<string> MyList
    {
        get => _myList;
        set => this.RaiseAndSetIfChanged(ref _myList, value);
    }
}

根据我的理解,订阅是普通的 .NET 对象.在 ViewModel 类之外没有引用.所以当我的 TestViewModel 超出范围(即 object 不再使用并替换为另一个)时,GarbageCollector 应该清理所有的东西在 ViewModel 内部,所以我不能在返回的 IDisposables 上手动调用 Dispose.

From my understanding the subscriptions are plain .NET objects. With no reference outside of the ViewModel class. So when my TestViewModel goes out of scope (i.e. the object is never used anymore and replaced with another one) the GarbageCollector should cleanup all the stuff inside the ViewModel, so I have not to manually call Dispose on the returned IDisposables.

我说得对吗?

编辑
ReactiveList 还可以保存其他 .NET 对象.此示例并非特定于不可变字符串类型.

Edit
The ReactiveList could also hold other .NET objects. This example is not specific to the immutable string type.

推荐答案

这是来自 Kent Boogart(ReactiveUI 维护者之一)对此事的意见:

This is from Kent Boogart (one of the ReactiveUI maintainers) opinion on the matter:

那么,假设...如果您在视图中使用 WhenActivated,您何时处理它返回的一次性物品?您必须将其存储在本地字段中并使视图可处理.但是谁来处理视图呢?您需要平台挂钩才能知道何时是处置它的合适时间——如果该视图在虚拟化场景中被重用,这不是一件小事.就是这样.

So, hypothetically...if you're using WhenActivated in a view, when do you dispose of the disposable that it returns? You'd have to store it in a local field and make the view disposable. But then who disposes of the view? You'd need platform hooks to know when an appropriate time to dispose it is - not a trivial matter if that view is reused in virtualization scenarios. So there's that.

当你执行一个反应式命令时呢?你是否把你得到的一次性用品储存起来,以便以后清理"它?我猜不会,而且有充分的理由.执行完成后,所有观察者都会自动取消订阅.通常,对具有有限生命周期(例如,通过超时)的管道的订阅不需要手动处理.处理此类订阅与处理 MemoryStream 一样有用.

And what about when you execute a reactive command? Do you store off the disposable you get so you can "clean it up" later? I'm gonna guess not, and for good reason. When the execution completes, all observers are auto-unsubscribed anyway. Generally, subscriptions to pipelines that have a finite lifetime (eg. via a timeout) need not be disposed manually. Disposing of such a subscription is about as useful as disposing of a MemoryStream.

除此之外,我发现虚拟机中的响应式代码尤其倾向于处理大量一次性代码.将所有这些一次性物品存储起来并尝试处置往往会使代码变得混乱并迫使 VM 本身成为一次性物品,从而进一步混淆问题.性能是另一个需要考虑的因素,尤其是在 Android 上.

In addition to this, I have found that reactive code in VMs in particular tends to juggle a lot of disposables. Storing all those disposables away and attempting disposal tends to clutter the code and force the VM itself to be disposable, further confusing matters. Perf is another factor to consider, particularly on Android.

所以我的建议源于这一切.我发现将那些需要处理的订阅放在 WhenActivated 中调用是最实用的方法.

So my advice stems from all this. I find that calling out those subscriptions that require disposal by wrapping them in WhenActivated is the most pragmatic approach.

这篇关于我应该总是处理 observable 的订阅吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆