public void FromEvent_SynchronizationContext() { var beforeSubscribeNull = false; var afterSubscribeNull = false; var subscribeOnCtx = false; var fstNext = false; var sndNext = false; var thdNext = false; var beforeDisposeNull = false; var afterDisposeNull = false; var disposeOnCtx = false; RunWithContext(new MyEventSyncCtx(), ctx => { var src = new MyEventSource(); var addCtx = default(SynchronizationContext); var remCtx = default(SynchronizationContext); var addEvt = new ManualResetEvent(false); var remEvt = new ManualResetEvent(false); var xs = Observable.FromEventPattern <MyEventArgs>(h => { addCtx = SynchronizationContext.Current; src.Bar += h; addEvt.Set(); }, h => { remCtx = SynchronizationContext.Current; src.Bar -= h; remEvt.Set(); }); Assert.Null(addCtx); Assert.Null(remCtx); var d = default(IDisposable); var res = new List <int>(); var s = new Thread(() => { beforeSubscribeNull = object.ReferenceEquals(SynchronizationContext.Current, null); d = xs.Subscribe(e => res.Add(e.EventArgs.Value)); afterSubscribeNull = object.ReferenceEquals(SynchronizationContext.Current, null); }); s.Start(); s.Join(); addEvt.WaitOne(); subscribeOnCtx = object.ReferenceEquals(addCtx, ctx); src.OnBar(42); fstNext = res.SequenceEqual(new[] { 42 }); src.OnBar(43); sndNext = res.SequenceEqual(new[] { 42, 43 }); var u = new Thread(() => { beforeDisposeNull = object.ReferenceEquals(SynchronizationContext.Current, null); d.Dispose(); afterDisposeNull = object.ReferenceEquals(SynchronizationContext.Current, null); }); u.Start(); u.Join(); remEvt.WaitOne(); disposeOnCtx = object.ReferenceEquals(remCtx, ctx); src.OnBar(44); thdNext = res.SequenceEqual(new[] { 42, 43 }); }); Assert.True(beforeSubscribeNull); Assert.True(subscribeOnCtx); Assert.True(afterSubscribeNull); Assert.True(fstNext); Assert.True(sndNext); Assert.True(thdNext); Assert.True(beforeDisposeNull); Assert.True(disposeOnCtx); Assert.True(afterDisposeNull); }
public void FromEvent_ImplicitPublish() { var src = new MyEventSource(); var addCount = 0; var remCount = 0; var xs = Observable.FromEventPattern <MyEventArgs>(h => { addCount++; src.Bar += h; }, h => { src.Bar -= h; remCount++; }, Scheduler.Immediate); Assert.Equal(0, addCount); Assert.Equal(0, remCount); src.OnBar(41); var fst = new List <int>(); var d1 = xs.Subscribe(e => fst.Add(e.EventArgs.Value)); Assert.Equal(1, addCount); Assert.Equal(0, remCount); src.OnBar(42); Assert.True(fst.SequenceEqual(new[] { 42 })); d1.Dispose(); Assert.Equal(1, addCount); Assert.Equal(1, remCount); var snd = new List <int>(); var d2 = xs.Subscribe(e => snd.Add(e.EventArgs.Value)); Assert.Equal(2, addCount); Assert.Equal(1, remCount); src.OnBar(43); Assert.True(fst.SequenceEqual(new[] { 42 })); Assert.True(snd.SequenceEqual(new[] { 43 })); var thd = new List <int>(); var d3 = xs.Subscribe(e => thd.Add(e.EventArgs.Value)); Assert.Equal(2, addCount); Assert.Equal(1, remCount); src.OnBar(44); Assert.True(fst.SequenceEqual(new[] { 42 })); Assert.True(snd.SequenceEqual(new[] { 43, 44 })); Assert.True(thd.SequenceEqual(new[] { 44 })); d2.Dispose(); Assert.Equal(2, addCount); Assert.Equal(1, remCount); src.OnBar(45); Assert.True(fst.SequenceEqual(new[] { 42 })); Assert.True(snd.SequenceEqual(new[] { 43, 44 })); Assert.True(thd.SequenceEqual(new[] { 44, 45 })); d3.Dispose(); Assert.Equal(2, addCount); Assert.Equal(2, remCount); src.OnBar(46); Assert.True(fst.SequenceEqual(new[] { 42 })); Assert.True(snd.SequenceEqual(new[] { 43, 44 })); Assert.True(thd.SequenceEqual(new[] { 44, 45 })); }