The Intro To RX book describes the return value on OnSubscribe as IDisposible
and notes that subscriptions should be disposed of when OnError
and OnCompleted
are called.
An interesting thing to consider is that when a sequence completes or errors, you should still dispose of your subscription.
From Intro to RX: Lifetime Management, OnError and OnCompleted
Why is this?
For reference, this is the class I'm currently working on. I'm probably going to submit it to code review at some point.
using System;
using System.Reactive;
using System.Reactive.Linq;
using System.Reactive.Subjects;
/// <summary>
/// Provides a timeout mechanism that will not timeout if it is signalled often enough
/// </summary>
internal class TrafficTimeout
{
private readonly Action onTimeout;
private object signalLock = new object();
private IObserver<Unit> signals;
/// <summary>
/// Initialises a new instance of the <see cref="TrafficTimeout"/> class.
/// </summary>
/// <param name="timeout">The duration to wait after receiving signals before timing out.</param>
/// <param name="onTimeout">The <see cref="Action"/> to perform when the the timeout duration expires.</param>
public TrafficTimeout(TimeSpan timeout, Action onTimeout)
{
// Subscribe to a throttled observable to trigger the expirey
var messageQueue = new BehaviorSubject<Unit>(Unit.Default);
IDisposable subscription = null;
subscription = messageQueue.Throttle(timeout).Subscribe(
p =>
{
messageQueue.OnCompleted();
messageQueue.Dispose();
});
this.signals = messageQueue.AsObserver();
this.onTimeout = onTimeout;
}
/// <summary>
/// Signals that traffic has been received.
/// </summary>
public void Signal()
{
lock (this.signalLock)
{
this.signals.OnNext(Unit.Default);
}
}
}