3
votes

Hi I've been thinking for some time that Subject<T> disposes all the subscriptions based on it if you manually call its Dispose method. But I've recently found it doesn't work that way, it just clears its inner collection of observers and substitutes it with a DisposedObserver helper class instance.

I found myself a little confused about the behaviour, just assumed that the "normal" would be just propagate and dispose all the suscribers. Later, trying to figure out why is designed this way, I guessed a couple of reasons why they designed this way.

  • The suscriber may be a composition that depents partially on the subject , so full propagation of disposal doesn't make sense. ie. Merge is not disposed just because one of the sources was disposed, as everyone expects.
  • Subject.Dispose It is semantically equivalent to a continuation with Observable.Never from the side of the observer. The Subject.Dispose caller can also call OnComplete or OnError if wanted to signal error or completion before disposal (because they are on the same scope).

Edit Note: Sorry for the unclear question. I already understand how to use it, this was more a design question. Let me state it more clearly.

Why do you think the designers of Rx made Dispose behaviour that way?

(the two points above are my answer trial)

1
You should add your answers as an answer rather than put them in the question. - James World
The more interesting question (for me at least) is why they even made a Subject IDisposable. - Brandon
It's a good question - as far as I can tell, Rx itself makes no use of it. - James World
It looks like a big off switch - the Dispose call swaps the internal reference to Observers for a special DisposedObserver that makes further OnXXX calls a NOP and it causes an ObjectDisposed reference to be thrown to subsequent callers of Subscribe - I can see that being useful if you want to prevent any further Subscribers to a sequence. - James World
ObjectDisposed exception I mean... - James World

1 Answers

7
votes

A subject should indicate it is done by sending OnComplete or possibly OnError. This is idiomatically and grammatically correct Rx. Subscribers are responsible for ending their subscriptions by disposing them. You should write Observables such that they clean up resources once they are "done" even if subscribers have not unsubscribed.