Sample<TSource>
using System.
Reactive.
Concurrency;
using System.
Reactive.
Disposables;
namespace System.
Reactive.
Linq.
ObservableImpl
{
internal sealed class Sample<
TSource> :
Producer<
TSource,
Sample<
TSource>.
_>
{
internal sealed class _ :
Sink<
TSource>,
IObserver<
TSource>
{
private object _gate =
new object();
private IDisposable _sourceSubscription;
private bool _hasValue;
private TSource _value;
private bool _atEnd;
public _(
IObserver<
TSource>
observer,
IDisposable cancel)
:
base(
observer,
cancel)
{
}
public IDisposable Run(
Sample<
TSource>
parent)
{
SingleAssignmentDisposable singleAssignmentDisposable = (
SingleAssignmentDisposable)(
_sourceSubscription =
new SingleAssignmentDisposable());
singleAssignmentDisposable.
Disposable =
ObservableExtensions.
SubscribeSafe<
TSource>(
parent.
_source, (
IObserver<
TSource>)
this);
return StableCompositeDisposable.
Create(
singleAssignmentDisposable,
parent.
_scheduler.
SchedulePeriodic(
parent.
_interval,
Tick));
}
private void Tick()
{
lock (
_gate) {
if (
_hasValue) {
_hasValue =
false;
_observer.
OnNext(
_value);
}
if (
_atEnd) {
_observer.
OnCompleted();
base.
Dispose();
}
}
}
public void OnNext(
TSource value)
{
lock (
_gate) {
_hasValue =
true;
_value =
value;
}
}
public void OnError(
Exception error)
{
lock (
_gate) {
_observer.
OnError(
error);
base.
Dispose();
}
}
public void OnCompleted()
{
lock (
_gate) {
_atEnd =
true;
_sourceSubscription.
Dispose();
}
}
}
private readonly IObservable<
TSource>
_source;
private readonly TimeSpan _interval;
private readonly IScheduler _scheduler;
public Sample(
IObservable<
TSource>
source,
TimeSpan interval,
IScheduler scheduler)
{
_source =
source;
_interval =
interval;
_scheduler =
scheduler;
}
protected override _ CreateSink(
IObserver<
TSource>
observer,
IDisposable cancel)
{
return new _(
observer,
cancel);
}
protected override IDisposable Run(
_ sink)
{
return sink.
Run(
this);
}
}
}