grimus
grimus

Reputation: 3175

Does an IDisposable from IObservable.Subscribe() hold a reference to the source?

Does an IDisposable from IObservable.Subscribe() hold a reference to the IObservable?

If the IDisposable is rooted and can't be garbage collected, does it hold a reference to the subscription and the IObservable?

In other words, if the intended lifetime of the IObservable is shorter than the lifetime of the returned IDisposable, can the IObservable be GC'ed?

Upvotes: 1

Views: 174

Answers (3)

Enigmativity
Enigmativity

Reputation: 117029

Here's a test that seems to show that the observable is GC'ed:

var xs = Observable.Timer(TimeSpan.FromSeconds(1.0));
var disposable = xs.Subscribe(x => Console.WriteLine(x));

var wr = new WeakReference(xs);
xs = null;

Thread.Sleep(2000);

Console.WriteLine(wr.IsAlive); // True

GC.Collect();

Console.WriteLine(wr.IsAlive); // False

Upvotes: 0

grimus
grimus

Reputation: 3175

I created some quick test code for this, and it seems that the IDisposable will keep a reference and hold the IObservable in memory. Or at least very well could, as Jason says.

Subject<int> subject = new Subject<int>();
WeakReference wr = new WeakReference(subject);

IDisposable disposable = subject.Subscribe(i => Console.WriteLine("Next: " + i));

subject.OnNext(5);
subject.OnNext(10);
subject = null;

GC.Collect();
Console.WriteLine(wr.IsAlive ? "Subject is still alive." : "Subject is not alive.");

When written as above, the weak reference will still be alive. If I comment out the disposable assignment, then subject gets GC'ed.

/*IDisposable disposable = */ subject.Subscribe(i => Console.WriteLine("Next: " + i));

Upvotes: 0

jason
jason

Reputation: 241601

It depends on the implementation. It doesn't have to, but it very well could.

Upvotes: 1

Related Questions