Skip to content

Commit bf87332

Browse files
committed
Fix duplicate emission in Delay with immediate selector
1 parent 1ff45fb commit bf87332

File tree

2 files changed

+28
-8
lines changed
  • Rx.NET/Source
    • src/System.Reactive/Linq/Observable
    • tests/Tests.System.Reactive/Tests/Linq/Observable

2 files changed

+28
-8
lines changed

Rx.NET/Source/src/System.Reactive/Linq/Observable/Delay.cs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,7 @@ private sealed class DelayObserver : SafeObserver<TDelay>
681681
{
682682
private readonly _ _parent;
683683
private readonly TSource _value;
684+
private bool _once;
684685

685686
public DelayObserver(_ parent, TSource value)
686687
{
@@ -690,12 +691,16 @@ public DelayObserver(_ parent, TSource value)
690691

691692
public override void OnNext(TDelay value)
692693
{
693-
lock (_parent._gate)
694+
if (!_once)
694695
{
695-
_parent.ForwardOnNext(_value);
696+
_once = true;
697+
lock (_parent._gate)
698+
{
699+
_parent.ForwardOnNext(_value);
696700

697-
_parent._delays.Remove(this);
698-
_parent.CheckDone();
701+
_parent._delays.Remove(this);
702+
_parent.CheckDone();
703+
}
699704
}
700705
}
701706

@@ -709,12 +714,15 @@ public override void OnError(Exception error)
709714

710715
public override void OnCompleted()
711716
{
712-
lock (_parent._gate)
717+
if (!_once)
713718
{
714-
_parent.ForwardOnNext(_value);
719+
lock (_parent._gate)
720+
{
721+
_parent.ForwardOnNext(_value);
715722

716-
_parent._delays.Remove(this);
717-
_parent.CheckDone();
723+
_parent._delays.Remove(this);
724+
_parent.CheckDone();
725+
}
718726
}
719727
}
720728
}

Rx.NET/Source/tests/Tests.System.Reactive/Tests/Linq/Observable/DelayTest.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1405,6 +1405,18 @@ public void Delay_Duration_SelectorThrows2()
14051405
);
14061406
}
14071407

1408+
[Fact]
1409+
public void Delay_Duration_Selector_Immediately()
1410+
{
1411+
var list = new List<int>();
1412+
1413+
Observable.Range(1, 5)
1414+
.Delay(_ => Observable.Return(1))
1415+
.Subscribe(list.Add);
1416+
1417+
Assert.Equal(new List<int>() { 1, 2, 3, 4, 5 }, list);
1418+
}
1419+
14081420
[Fact]
14091421
public void Delay_Duration_InnerDone()
14101422
{

0 commit comments

Comments
 (0)