我在Rx的第一步,我被困在这里:
public class DisposableResourceDemo : IDisposable
{
public DisposableResourceDemo() {
Console.WriteLine("DisposableResourceDemo constructor.");
}
public void Dispose() {
Console.WriteLine("DisposableResourceDemo.Dispose()");
}
public void SideEffect() {
Console.WriteLine("DisposableResourceDemo.SideEffect()");
}
}
[Test]
public void ShowBehaviourOfRxUsing()
{
var test = Observable.Using(() =>
{
// This should happen exactly once, independent of number of subscriptions,
// object should be disposed on last subscription disposal or OnCompleted call
return new DisposableResourceDemo();
},
(dr) =>
{
return Observable.Create<string>(
(IObserver<string> observer) =>
{
dr.SideEffect();
var dummySource = Observable.Return<string>("Some Text");
return dummySource.Subscribe(observer);
});
}).Publish().RefCount();
Console.WriteLine("before 1st subscription.");
test.Subscribe(Console.WriteLine, () => Console.WriteLine("OnCompleted in 1st."));
Console.WriteLine("before 2nd subscription.");
test.Subscribe(Console.WriteLine, () => Console.WriteLine("OnCompleted in 2nd."));
}
令我惊讶的是,上面的代码产生了
before 1st subscription.
DisposableResourceDemo constructor.
DisposableResourceDemo.SideEffect()
Some Text
OnCompleted in 1st.
DisposableResourceDemo.Dispose()
before 2nd subscription.
--> [happy with missing "Some Text" here]
OnCompleted in 2nd.
--> [unhappy with second instantiation here]
DisposableResourceDemo constructor.
DisposableResourceDemo.SideEffect()
DisposableResourceDemo.Dispose()
请注意,在两个订阅之后手动调用Connect()不是我想要的,尽管输出是预期的。
答案 0 :(得分:0)
我不完全确定你在这里想要实现的目标。您似乎想要共享可观察序列及其相关资源。所以标准的方法是使用你从.Replay()和.Publish()等获得的ConnectableObservable类型。
你说你不想使用.Connect(),而是使用非常常见的.RefCount()。但是,您的序列完成了。您还使用Extension方法Subscribe(...),它将在内部创建一个Auto分离观察器,即当序列完成时,它将断开连接。
所以我的问题是,内部序列是否真的完成了? 如果答案是肯定的,那么为什么第二个订阅会收到OnComplete通知......它已经发生了,它已经过去了。也许你确实想重播OnComplete,在这种情况下也许.Replay(1)就是你想要的。 如果答案为否,则可以通过在.Publish()之前或Observable.Return之后放置一个Concat(Observable.Never&lt; string&gt;())来轻松解决此问题。