Пример #1
0
        public void CancelDelayedTest()
        {
            // prepare
            var syncContext        = new SynchronizationContext();
            var anotherSyncContext = new SynchronizationContext();
            var stopWatch          = new Stopwatch().Also((it) => it.Start());

            // cancel before execution
            var executed = false;
            var token    = syncContext.PostDelayed(() =>
            {
                executed = true;
            }, 500);

            Thread.Sleep(200);
            Assert.IsTrue(syncContext.CancelDelayed(token), "Call-back cancellation should be successful.");
            Thread.Sleep(500);
            Assert.IsFalse(executed, "Call-back should not be executed after cancellation.");
            Assert.IsFalse(syncContext.CancelDelayed(token), "Call-back cancellation should be failed.");

            // cancel after execution
            executed = false;
            token    = syncContext.PostDelayed(() =>
            {
                executed = true;
            }, 200);
            Thread.Sleep(500);
            Assert.IsTrue(executed, "Call-back should be executed.");
            Assert.IsFalse(syncContext.CancelDelayed(token), "Call-back cancellation should be failed after execution.");

            // cancel by another synchronization context
            executed = false;
            token    = syncContext.PostDelayed(() =>
            {
                executed = true;
            }, 200);
            Assert.IsFalse(anotherSyncContext.CancelDelayed(token), "Call-back cancellation should be failed by another synchronization context.");
            Thread.Sleep(500);
            Assert.IsTrue(executed, "Call-back should be executed.");
        }
Пример #2
0
        public void PostDelayedTest()
        {
            // prepare
            var syncContext = new SynchronizationContext();
            var stopWatch   = new Stopwatch().Also((it) => it.Start());

            // post without delay time
            var syncLock      = new object();
            var postTime      = stopWatch.ElapsedMilliseconds;
            var executionTime = 0L;

            lock (syncLock)
            {
                syncContext.PostDelayed(() =>
                {
                    executionTime = stopWatch.ElapsedMilliseconds;
                    lock (syncLock)
                    {
                        Monitor.Pulse(syncLock);
                    }
                }, 0);
                Assert.IsTrue(Monitor.Wait(syncLock, 1000), "Posted call-back not executed.");
                Assert.GreaterOrEqual(executionTime - postTime, 0, "Call-back executed too early.");
                Assert.LessOrEqual(executionTime - postTime, 200, "Call-back executed too late.");
            }

            // post with delayed time on multi-threads
            var completedCount = 0;
            var exception      = (Exception?)null;

            lock (syncLock)
            {
                for (var i = 0; i < 100; ++i)
                {
                    ThreadPool.QueueUserWorkItem((_) =>
                    {
                        var delayedTime   = this.random.Next(10, 500);
                        var localPostTime = stopWatch.ElapsedMilliseconds;
                        syncContext.PostDelayed(() =>
                        {
                            try
                            {
                                var actualDelayedTime = (stopWatch.ElapsedMilliseconds - localPostTime);
                                Assert.GreaterOrEqual(actualDelayedTime, delayedTime, "Call-back executed too early.");
                                Assert.LessOrEqual(actualDelayedTime, delayedTime + 100, "Call-back executed too late.");
                            }
                            catch (Exception ex)
                            {
                                exception = ex;
                            }
                            finally
                            {
                                lock (syncLock)
                                {
                                    ++completedCount;
                                    if (completedCount == 100 || exception != null)
                                    {
                                        Monitor.Pulse(syncLock);
                                    }
                                }
                            }
                        }, delayedTime);
                    });
                }
                Assert.IsTrue(Monitor.Wait(syncLock, 60000), "Unable to complete waiting for posting delayed call-back on multi-threads.");
            }
        }