我有IObservable<byte[]>
我使用一些中间步骤转换为IObservable<XDocument>
:
var observedXDocuments =
from b in observedBytes
// Lot of intermediate steps to transform byte arrays into XDocuments
select xDoc;
在某个时间点,我对观察到的XDocument
感兴趣所以我订阅IObserver<XDocument>
。在以后的某个时间点,我想订阅另一个IObserver<XDocument>
并处理旧的。{/ p>
如何在一次原子操作中执行此操作,而不会丢失任何观察到的XDocument
?我可以做类似的事情:
oldObserver.Dispose();
observedXDocuments.Subscribe(newObserver);
我很担心,在这两个电话之间,我可以松开XDocument
。如果我切换两个电话,可能会发生两次相同的XDocument
。
答案 0 :(得分:6)
我可能会添加一层间接。编写一个名为ExchangeableObserver的类,将其订阅到您的observable,并保持永久订阅。 ExchangeableObserver的工作是将所有内容委托给给定的子观察者。但是程序员可以随时更改被委派给的子观察者。在我的例子中,我有一个Exchange()方法。类似的东西:
public class ExchangeableObserver<T> : IObserver<T> {
private IObserver<T> inner;
public ExchangeableObserver(IObserver<T> inner) {
this.inner=inner;
}
public IObserver<T> Exchange(IObserver<T> newInner) {
return Interlocked.Exchange(ref inner, newInner);
}
public void OnNext(T value) {
inner.OnNext(value);
}
public void OnCompleted() {
inner.OnCompleted();
}
public void OnError(Exception error) {
inner.OnError(error);
}
}
答案 1 :(得分:1)
你可以使用一个信号量,当IObservable<byte[]>
为IObservable<XDocument>
做准备时,不会发生观察者变化。
伪代码如何做到这一点(不是testet)
System.Threading.ReaderWriterLockSlim criticalSection
= new System.Threading.ReaderWriterLockSlim(...);
... converting from `IObservable<byte[]>` to `IObservable<XDocument>`
criticalSection.EnterReadLock();
Call IObservable<XDocument>
criticalSection.ExitReadLock();
.... replacing IObservable<XDocument>
criticalSection.EnterWriteLock();
Call change IObservable<XDocument>
criticalSection.ExitWriteLock();
编辑:使用Call IObservable<XDocument>
> What exactly do you mean with the line `Call IObservable<XDocument>`?
我解释你的意外
> I have an `IObservable<byte[]>` that I transform
> into an `IObservable<XDocument>` using some intermediate steps...
您已为IObservable<byte[]>
注册了一个事件处理程序,可以从XDocument
创建byte[]
然后调用
触发IObservable<XDocument>
事件的东西。
Call IObservable<XDocument>
表示触发后续事件的代码