What I want to do is ensure that if the only reference to my observer is the observable, it get\'s garbage collected and stops receiving messages.
Say I have a control w
this is my implementation (quit simple one)
public class WeakObservable: IObservable
{
private IObservable _source;
public WeakObservable(IObservable source)
{
#region Validation
if (source == null)
throw new ArgumentNullException("source");
#endregion Validation
_source = source;
}
public IDisposable Subscribe(IObserver observer)
{
IObservable source = _source;
if(source == null)
return Disposable.Empty;
var weakObserver = new WaekObserver(observer);
IDisposable disp = source.Subscribe(weakObserver);
return disp;
}
}
public class WaekObserver: IObserver
{
private WeakReference> _target;
public WaekObserver(IObserver target)
{
#region Validation
if (target == null)
throw new ArgumentNullException("target");
#endregion Validation
_target = new WeakReference>(target);
}
private IObserver Target
{
get
{
IObserver target;
if(_target.TryGetTarget(out target))
return target;
return null;
}
}
#region IObserver Members
///
/// Notifies the observer that the provider has finished sending push-based notifications.
///
public void OnCompleted()
{
IObserver target = Target;
if (target == null)
return;
target.OnCompleted();
}
///
/// Notifies the observer that the provider has experienced an error condition.
///
/// An object that provides additional information about the error.
public void OnError(Exception error)
{
IObserver target = Target;
if (target == null)
return;
target.OnError(error);
}
///
/// Provides the observer with new data.
///
/// The current notification information.
public void OnNext(T value)
{
IObserver target = Target;
if (target == null)
return;
target.OnNext(value);
}
#endregion IObserver Members
}
public static class RxExtensions
{
public static IObservable ToWeakObservable(this IObservable source)
{
return new WeakObservable(source);
}
}
static void Main(string[] args)
{
Console.WriteLine("Start");
var xs = Observable.Interval(TimeSpan.FromSeconds(1));
Sbscribe(xs);
Thread.Sleep(2020);
Console.WriteLine("Collect");
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Console.WriteLine("Done");
Console.ReadKey();
}
private static void Sbscribe(IObservable source)
{
source.ToWeakObservable().Subscribe(v => Console.WriteLine(v));
}