| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 | // Licensed to the .NET Foundation under one or more agreements.// The .NET Foundation licenses this file to you under the MIT License.// See the LICENSE file in the project root for more information. using System;using System.Diagnostics;using System.Reactive.Concurrency;using System.Reactive.Disposables;using System.Threading;using Microsoft.Reactive.Testing;using Microsoft.VisualStudio.TestTools.UnitTesting;using Assert = Xunit.Assert;namespace ReactiveTests.Tests{    [TestClass]    public class SynchronizationContextSchedulerTest    {        [TestMethod]        public void SynchronizationContext_ArgumentChecking()        {            var ms = new MySync();            var s = new SynchronizationContextScheduler(ms);#pragma warning disable CA1806 // (Unused new instance.) We expect the constructor to throw.            ReactiveAssert.Throws<ArgumentNullException>(() => new SynchronizationContextScheduler(null));            ReactiveAssert.Throws<ArgumentNullException>(() => new SynchronizationContextScheduler(null, true));#pragma warning restore CA1806            ReactiveAssert.Throws<ArgumentNullException>(() => s.Schedule(42, default));            ReactiveAssert.Throws<ArgumentNullException>(() => s.Schedule(42, DateTimeOffset.Now, default));            ReactiveAssert.Throws<ArgumentNullException>(() => s.Schedule(42, TimeSpan.Zero, default));        }        [TestMethod]        public void SynchronizationContext_Now()        {            var ms = new MySync();            var s = new SynchronizationContextScheduler(ms);            var res = s.Now - DateTime.Now;            Assert.True(res.Seconds < 1);        }        [TestMethod]        public void SynchronizationContext_ScheduleAction()        {            var ms = new MySync();            var s = new SynchronizationContextScheduler(ms);            var ran = false;            s.Schedule(() => { ran = true; });            Assert.True(ms.Count == 1);            Assert.True(ran);        }        [TestMethod]        public void SynchronizationContext_ScheduleAction_TimeSpan()        {            var ms = new MySync();            var s = new SynchronizationContextScheduler(ms);            var e = new ManualResetEvent(false);            s.Schedule(TimeSpan.FromMilliseconds(1), () => { e.Set(); });            e.WaitOne();            Assert.True(ms.Count == 1);        }        [TestMethod]        public void SynchronizationContext_ScheduleAction_DateTimeOffset()        {            var ms = new MySync();            var s = new SynchronizationContextScheduler(ms);            var e = new ManualResetEvent(false);            s.Schedule(DateTimeOffset.Now.AddMilliseconds(100), () => { e.Set(); });            e.WaitOne();            Assert.True(ms.Count >= 1); // Can be > 1 in case of timer queue retry operations.        }        [TestMethod]        public void SynchronizationContext_ScheduleActionError()        {            var ms = new MySync();            var s = new SynchronizationContextScheduler(ms);            var ex = new Exception();            try            {                s.Schedule(() => { throw ex; });                Assert.True(false);            }            catch (Exception e)            {                Assert.Same(e, ex);            }            Assert.True(ms.Count == 1);        }        [TestMethod]        public void SynchronizationContext_ScheduleActionDue()        {            var ms = new MySync();            var s = new SynchronizationContextScheduler(ms);            var evt = new ManualResetEvent(false);            var sw = new Stopwatch();            sw.Start();            s.Schedule(TimeSpan.FromSeconds(0.2), () => { sw.Stop(); evt.Set(); });            evt.WaitOne();            Assert.True(sw.ElapsedMilliseconds > 180, "due " + sw.ElapsedMilliseconds);            Assert.True(ms.Count == 1);        }        private class MySync : SynchronizationContext        {            public int Count { get; private set; }            public override void Post(SendOrPostCallback d, object state)            {                Count++;                d(state);            }            public override void Send(SendOrPostCallback d, object state)            {                throw new NotImplementedException();            }            public int Started { get; private set; }            public override void OperationStarted()            {                base.OperationStarted();                Started++;            }            public int Completed { get; private set; }            public override void OperationCompleted()            {                base.OperationCompleted();                Completed++;            }        }        [TestMethod]        public void SynchronizationContext_StartedCompleted()        {            var ms = new MySync();            var s = new SynchronizationContextScheduler(ms);            var started = 0;            s.Schedule(42, TimeSpan.Zero, (self, x) => { started = ms.Started; return Disposable.Empty; });            Assert.True(started == 1);            Assert.True(ms.Count == 1);            Assert.True(ms.Completed == 1);        }        [TestMethod]        public void SynchronizationContext_DontPost_Different()        {            var ms = new MySync();            var s = new SynchronizationContextScheduler(ms, false);            var ran = false;            s.Schedule(() => { ran = true; });            Assert.True(ms.Count == 1);            Assert.True(ran);        }        [TestMethod]        public void SynchronizationContext_DontPost_Same()        {            var count = 0;            var ran = false;            var t = new Thread(() =>            {                var ms = new MySync();                SynchronizationContext.SetSynchronizationContext(ms);                var s = new SynchronizationContextScheduler(ms, false);                s.Schedule(() => { ran = true; });                count = ms.Count;            });            t.Start();            t.Join();            Assert.True(count == 0 /* no post */);            Assert.True(ran);        }        [TestMethod]        public void SynchronizationContext_AlwaysPost_Different()        {            var ms = new MySync();            var s = new SynchronizationContextScheduler(ms, true);            var ran = false;            s.Schedule(() => { ran = true; });            Assert.True(ms.Count == 1);            Assert.True(ran);        }        [TestMethod]        public void SynchronizationContext_AlwaysPost_Same()        {            var count = 0;            var ran = false;            var t = new Thread(() =>            {                var ms = new MySync();                SynchronizationContext.SetSynchronizationContext(ms);                var s = new SynchronizationContextScheduler(ms, true);                s.Schedule(() => { ran = true; });                count = ms.Count;            });            t.Start();            t.Join();            Assert.True(count == 1 /* post */);            Assert.True(ran);        }    }}
 |