Skip to content

BUG: RefCount with MinObservers > 1 Behaves Unexpectedly #2173

Open
@mikeronayne

Description

@mikeronayne

Code

Subject<int> subj = new();

var refCount = subj.Publish().RefCount(minObservers: 2);

subj.OnNext(1);

var sub1 = refCount.Subscribe(c => Console.WriteLine($"sub1: {c}"));

subj.OnNext(2);

var sub2 = refCount.Subscribe(c => Console.WriteLine($"sub2: {c}"));

subj.OnNext(3);

sub1.Dispose();

subj.OnNext(4);

var sub3 = refCount.Subscribe(c => Console.WriteLine($"sub3: {c}"));

subj.OnNext(5);

var sub4 = refCount.Subscribe(c => Console.WriteLine($"sub4: {c}"));

subj.OnNext(6);

sub2.Dispose();

sub3.Dispose();

sub4.Dispose();

Expected Output

I would expect not to receive values until sub2 has subscribed. Then I would expect not to receive values after sub1 is disposed. Then I would expect to receive values again after sub3 has subscribed.

sub1: 3
sub2: 3
sub2: 5
sub3: 5
sub2: 6
sub3: 6
sub4: 6

Actual Output

  1. sub2 should not have received value 4 since we were below minObservers at that point.
  2. Definitely shouldn't have gotten an exception on sub3 subscribing.
sub1: 3
sub2: 3
sub2: 4

InvalidOperationException: Disposable has already been assigned.
at System.Reactive.Disposables.SingleAssignmentDisposableValue.set_Disposable(IDisposable value) 
at System.Reactive.Linq.ObservableImpl.RefCount`1.Eager._.Run()   at System.Reactive.Linq.ObservableImpl.RefCount`1.Eager.Run(_ sink) 
at System.Reactive.Producer`2.<>c.<SubscribeRaw>b__1_0(ValueTuple`2 tuple) 
at System.Reactive.Concurrency.Scheduler.<>c__75`1.<ScheduleAction>b__75_0(IScheduler _, ValueTuple`2 tuple)
at System.Reactive.Concurrency.CurrentThreadScheduler.Schedule[TState](TState state, TimeSpan dueTime, Func`3 action)
at System.Reactive.Concurrency.LocalScheduler.Schedule[TState](TState state, Func`3 action)
at System.Reactive.Concurrency.Scheduler.ScheduleAction[TState](IScheduler scheduler, TState state, Action`1 action)
at System.Reactive.Producer`2.SubscribeRaw(IObserver`1 observer, Boolean enableSafeguard)
at System.Reactive.Producer`2.Subscribe(IObserver`1 observer)
at System.ObservableExtensions.Subscribe[T](IObservable`1 source, Action`1 onNext)   at UserQuery.Main(), line 21

If this IS expected and not a bug, would love an explanation of what I'm misunderstanding. Thank you!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions