What's the difference between .Dispose()
and .OnCompleted()
call on a Subject
?
Usually i dispose subscription to stop listening an observable and complete a subject when it's no longer useful anywhere on the code,
What's the difference between .Dispose()
and .OnCompleted()
call on a Subject
?
Usually i dispose subscription to stop listening an observable and complete a subject when it's no longer useful anywhere on the code,
There is a very important semantic difference between calling .Dispose()
and .OnCompleted()
on a subject.
Consider this code:
Subject<int> subject = new Subject<int>();
IObservable<int[]> query = subject.ToArray();
IDisposable subscription =
query
.Subscribe(xs => Console.WriteLine(String.Concat(xs)));
subject.OnNext(1);
subject.OnNext(2);
If I then call subject.OnCompleted()
I get 12
written to the Console. If, however, I call subject.Dispose()
then nothing gets printed.
Some operators, like .ToArray()
in my example code, expect the .OnCompleted()
call to produce any value.
It is important to understand what queries you are performing on the subject
to know how to end it properly - there are situations where both ways are valid.
I feel, though, that you are doing the right things with disposing of subscriptions and completing subjects.
Usually i dispose subscription to stop listening an observable and complete a subject when it's no longer usefull[sic] anywhere on the code
I think you have those backwards. I'm not familiar with rx.net, but I do know the IDisposable and Observable patterns. IDisposable is used to release resources from an object when you are completely done with it and it's no longer useful. OnCompleted is for when you are done observing (the provider has finished sending notifications), even if the object might still have other uses.
According to the documentation of the
Subject<T>.Dispose
method:It seems that attempting to do anything with a
Subject
after disposing it, results to anObjectDisposedException
. You can'tSubscribe
to a disposedSubject
for example. Any subscriptions that are active at the time theSubject
is disposed, will be disposed too, and the unsubscribed observers will not receiveOnCompleted
notifications.On the contrary a subject that has been completed by calling its
OnCompleted
method can still be subscribed at any time, in which case the subscribed observer will receive instantly anOnCompleted
notification. Of course if the completed subject is one of the buffered types like theReplaySubject
, then the observers will receive a number ofOnNext
notifications before the finalOnCompleted
.Personally I would consider calling
Dispose
to aReplaySubject
that is about to be discarded, in order to accelerate the recovery of the RAM used by its internal buffer. I am not sure if this would make any difference though, since theDispose
is generally supposed to release unmanaged resources, and the memory used by the buffer is most probably managed.