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()を手動で呼び出すことは、ここで必要なことではないことに注意してください。ただし、出力は期待どおりです。