我应该总是处理 observable 的订阅吗? [英] Should I always dispose subscriptions of observables?
问题描述
当 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屋!