我有一个Observable.Timer(TimeSpan)多次,但在几个地方我使用了Observable.Timer(DateTimeOffset)来触发当时的事件,但我相信它会阻止我的进程退出。
DateTimeOffset offset = new DateTimeOffset(minStart);
Observable.Timer(offset)
.Subscribe(_ =>
{
UpdateActive();
});
这段代码在我的ViewModel和Window Closed中,进程仍然在后台运行,通常在我使用Observable.Timer(TimeSpan)的地方自动处理,为什么不呢?
我做错了什么或是错误吗?或者我错过了什么?
答案 0 :(得分:1)
鉴于您正在使用其中一种Subscribe()
扩展方法,假设您使用的是最新版本的RX,则observable应该在完成时释放所有订阅者。你的观察结果是在一个案例中完成而不是在另一个案例中完成吗?
如果您的观察结果尚未完成(即如果offset
代表的时间尚未发生),那么当您关闭窗口时,没有任何内容会自动取消订阅。这是introtorx site在这件事上的重点(强调我的):
考虑到这一点,我认为注意订阅是谨慎的 不会自动处理。你可以放心地假设 返回给你的IDisposable实例没有 终结者,当它超出范围时不会被收集。 如果你 调用一个Subscribe方法并忽略返回值,你输了 你唯一的取消订阅手柄。订阅仍然存在, 并且您实际上已经失去了对此资源的访问权限 导致内存泄漏并运行不需要的进程。
答案 1 :(得分:0)
使用接受Observable.Timer
的{{1}}重载不会导致进程保持打开状态;别的东西对此负责。
但是,不向DateTimeOffset
部署订阅的后果是您将泄漏计时器资源。
您应该保留基于计时器和事件的可观察对象的Observable.Timer
订阅句柄并妥善处理它们;大多数WPF框架都为此提供了合适的事件。
一般情况下,我会跟踪并处理所有窗口范围的订阅,只是为了安全起见。有关示例,请参阅Convert Polling Web Service to RX。