我想要做的是确保如果对我的观察者的唯一引用是可观察的,它会被垃圾收集并停止接收消息。
假设我有一个带有列表框的控件,称为“消息”,后面的代码如下:
//Short lived display of messages (only while the user's viewing incoming messages)
public partial class MessageDisplay : UserControl
{
public MessageDisplay()
{
InitializeComponent();
MySource.IncomingMessages.Subscribe(m => Messages.Items.Add(m));
}
}
哪个连接到这个源:
//Long lived location for message store
static class MySource
{
public readonly static IObservable<string> IncomingMessages = new ReplaySubject<string>;
}
我不希望消息显示在不再可见后很长时间内仍保留在内存中。理想情况下,我想要一点扩展,这样我就可以写:
MySource.IncomingMessages.ToWeakObservable().Subscribe(m => Messages.Items.Add(m));
我也不想依赖 MessageDisplay 是一个用户控件这一事实,因为我稍后会想要使用 MessageDisplayViewModel 进行 MVVM 设置,而这不会是一个用户控件。
您可以将代理观察者订阅到可观察对象,该可观察对象持有对实际观察者的弱引用,并在实际观察者不再活动时处置订阅:
static IDisposable WeakSubscribe<T>(
this IObservable<T> observable, IObserver<T> observer)
{
return new WeakSubscription<T>(observable, observer);
}
class WeakSubscription<T> : IDisposable, IObserver<T>
{
private readonly WeakReference reference;
private readonly IDisposable subscription;
private bool disposed;
public WeakSubscription(IObservable<T> observable, IObserver<T> observer)
{
this.reference = new WeakReference(observer);
this.subscription = observable.Subscribe(this);
}
void IObserver<T>.OnCompleted()
{
var observer = (IObserver<T>)this.reference.Target;
if (observer != null) observer.OnCompleted();
else this.Dispose();
}
void IObserver<T>.OnError(Exception error)
{
var observer = (IObserver<T>)this.reference.Target;
if (observer != null) observer.OnError(error);
else this.Dispose();
}
void IObserver<T>.OnNext(T value)
{
var observer = (IObserver<T>)this.reference.Target;
if (observer != null) observer.OnNext(value);
else this.Dispose();
}
public void Dispose()
{
if (!this.disposed)
{
this.disposed = true;
this.subscription.Dispose();
}
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)