RefCount<TSource>
using System.
Reactive.
Disposables;
using System.
Reactive.
Subjects;
namespace System.
Reactive.
Linq.
ObservableImpl
{
internal sealed class RefCount<
TSource> :
Producer<
TSource,
RefCount<
TSource>.
_>
{
internal sealed class _ :
Sink<
TSource>,
IObserver<
TSource>
{
public _(
IObserver<
TSource>
observer,
IDisposable cancel)
:
base(
observer,
cancel)
{
}
public IDisposable Run(
RefCount<
TSource>
parent)
{
IDisposable subscription =
ObservableExtensions.
SubscribeSafe<
TSource>((
IObservable<
TSource>)
parent.
_source, (
IObserver<
TSource>)
this);
lock (
parent.
_gate) {
if (++
parent.
_count ==
1)
parent.
_connectableSubscription =
parent.
_source.
Connect();
}
return Disposable.
Create(
delegate {
subscription.
Dispose();
lock (
parent.
_gate) {
if (--
parent.
_count ==
0)
parent.
_connectableSubscription.
Dispose();
}
});
}
public void OnNext(
TSource value)
{
_observer.
OnNext(
value);
}
public void OnError(
Exception error)
{
_observer.
OnError(
error);
base.
Dispose();
}
public void OnCompleted()
{
_observer.
OnCompleted();
base.
Dispose();
}
}
private readonly IConnectableObservable<
TSource>
_source;
private readonly object _gate;
private int _count;
private IDisposable _connectableSubscription;
public RefCount(
IConnectableObservable<
TSource>
source)
{
_source =
source;
_gate =
new object();
_count =
0;
_connectableSubscription =
null;
}
protected override _ CreateSink(
IObserver<
TSource>
observer,
IDisposable cancel)
{
return new _(
observer,
cancel);
}
protected override IDisposable Run(
_ sink)
{
return sink.
Run(
this);
}
}
}