コード例 #1
0
        public void TestNotificationWithPredicateRef()
        {
            using (var testInst = new MonitorObject())
            {
                int result = 0;
                int state  = 0;
                var task   = Task.Run(() =>
                {
                    using (var waiter = testInst.Enter(60000))
                    {
                        if (waiter.Wait((ref int s) => Volatile.Read(ref s) > 0, ref state))
                        {
                            Interlocked.Exchange(ref result, 1);
                        }
                        else
                        {
                            Interlocked.Exchange(ref result, 2);
                        }
                    }
                });

                TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount);
                Assert.AreEqual(0, Volatile.Read(ref result));

                testInst.Pulse();
                Thread.Sleep(100);
                Assert.AreEqual(0, Volatile.Read(ref result));

                Interlocked.Increment(ref state);
                testInst.Pulse();
                TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref result));

                task.Wait();
            }
        }
コード例 #2
0
        public void TestExceptionFromPredicatePassed()
        {
            using (var testInst = new MonitorObject())
            {
                int result = 0;
                int state  = 0;
                var task   = Task.Run(() =>
                {
                    using (var waiter = testInst.Enter(60000))
                    {
                        if (waiter.Wait((s) => { if (Volatile.Read(ref state) > 0)
                                                 {
                                                     throw new ApplicationException();
                                                 }
                                                 return(false); }, new object()))
                        {
                            Interlocked.Exchange(ref result, 1);
                        }
                        else
                        {
                            Interlocked.Exchange(ref result, 2);
                        }
                    }
                });

                TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount);
                Assert.AreEqual(0, Volatile.Read(ref result));

                testInst.Pulse();
                Thread.Sleep(1);
                Assert.AreEqual(0, Volatile.Read(ref result));

                Interlocked.Increment(ref state);
                testInst.Pulse();
                TimingAssert.AreEqual(10000, 0, () => testInst.WaiterCount);
                Assert.AreEqual(0, result);

                try
                {
                    task.Wait();
                }
                catch (AggregateException aE)
                {
                    if (aE.InnerExceptions.Count != 1 || !(aE.InnerExceptions[0] is ApplicationException))
                    {
                        throw;
                    }
                }
            }
        }
コード例 #3
0
            public bool TryTake(out T value, int timeout, CancellationToken token)
            {
                bool result = false;

                using (var waiter = WaiterEmpty.Enter(timeout, token))
                {
                    if (waiter.Wait(s => { Assert.IsTrue(Monitor.IsEntered(s.WaiterEmpty)); return(s.ItemCount > 0); }, this))
                    {
                        Assert.IsTrue(Monitor.IsEntered(WaiterEmpty));
                        bool dRes = Queue.TryDequeue(out value);
                        Assert.IsTrue(dRes);
                        Interlocked.Decrement(ref ItemCount);
                        result = true;
                    }
                    else
                    {
                        Assert.IsTrue(Monitor.IsEntered(WaiterEmpty));
                        value  = default(T);
                        result = false;
                    }
                }

                if (result)
                {
                    WaiterFull.Pulse();
                }

                return(result);
            }
コード例 #4
0
            public bool TryAdd(T value, int timeout, CancellationToken token)
            {
                bool result = false;

                using (var waiter = WaiterFull.Enter(timeout, token))
                {
                    if (waiter.Wait(s => { Assert.IsTrue(Monitor.IsEntered(s.WaiterFull)); return(s.ItemCount < s.MaxCount); }, this))
                    {
                        Assert.IsTrue(Monitor.IsEntered(WaiterFull));
                        Queue.Enqueue(value);
                        Interlocked.Increment(ref ItemCount);
                        result = true;
                    }
                    else
                    {
                        Assert.IsTrue(Monitor.IsEntered(WaiterFull));
                        result = false;
                    }
                }

                if (result)
                {
                    WaiterEmpty.Pulse();
                }


                return(result);
            }
コード例 #5
0
        public void TestSingleThreadWakeUpOnSignal()
        {
            using (var testInst = new MonitorObject())
            {
                int         exitCount = 0;
                int         state     = 0;
                List <Task> tasks     = new List <Task>();
                for (int i = 0; i < 6; i++)
                {
                    var task = Task.Run(() =>
                    {
                        using (var waiter = testInst.Enter())
                        {
                            waiter.Wait(_ => { return(Volatile.Read(ref state) > 0); }, (object)null);
                            Interlocked.Increment(ref exitCount);
                        }
                    });
                    tasks.Add(task);
                }


                TimingAssert.AreEqual(10000, 6, () => testInst.WaiterCount);
                Interlocked.Increment(ref state);

                for (int i = 0; i < 6; i++)
                {
                    testInst.Pulse();
                    TimingAssert.AreEqual(10000, 5 - i, () => testInst.WaiterCount);
                    Thread.Sleep(50);
                    TimingAssert.AreEqual(10000, i + 1, () => Volatile.Read(ref exitCount));
                }

                Task.WaitAll(tasks.ToArray());
            }
        }
コード例 #6
0
        public void TestCancellationWorksInWaitNoParam()
        {
            using (var testInst = new MonitorObject())
            {
                int result = 0;
                CancellationTokenSource tokenSrc = new CancellationTokenSource();
                var task = Task.Run(() =>
                {
                    try
                    {
                        using (var waiter = testInst.Enter(60000, tokenSrc.Token))
                        {
                            while (!waiter.Wait())
                            {
                            }
                            Interlocked.Exchange(ref result, 1);
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        Interlocked.Exchange(ref result, 3);
                    }
                });

                testInst.Pulse();

                Thread.Sleep(100);
                Assert.AreEqual(0, Volatile.Read(ref result));

                tokenSrc.Cancel();
                TimingAssert.AreEqual(10000, 3, () => Volatile.Read(ref result));
            }
        }
コード例 #7
0
        public void TestNotificationReceived()
        {
            using (var testInst = new MonitorObject())
            {
                int result = 0;
                var task   = Task.Run(() =>
                {
                    using (var waiter = testInst.Enter(60000))
                    {
                        if (waiter.Wait())
                        {
                            Interlocked.Exchange(ref result, 1);
                        }
                        else
                        {
                            Interlocked.Exchange(ref result, 2);
                        }
                    }
                });

                TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount);
                Assert.AreEqual(0, Volatile.Read(ref result));

                testInst.Pulse();
                TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref result));

                task.Wait();
            }
        }
コード例 #8
0
        public void TestTimeoutWorks()
        {
            using (var testInst = new MonitorObject())
            {
                int result = 0;
                var task   = Task.Run(() =>
                {
                    using (var waiter = testInst.Enter(500))
                    {
                        if (waiter.Wait(_ => false, (object)null))
                        {
                            Interlocked.Exchange(ref result, 1);
                        }
                        else
                        {
                            Interlocked.Exchange(ref result, 2);
                        }
                    }
                });

                TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount);
                testInst.Pulse();
                TimingAssert.AreEqual(10000, 2, () => Volatile.Read(ref result));

                task.Wait();
            }
        }
コード例 #9
0
ファイル: DiskQueue.cs プロジェクト: nnikos123/dotNet-turbo
 /// <summary>
 /// Notifies that item was taken
 /// </summary>
 private void NotifyItemTaken()
 {
     Interlocked.Decrement(ref _itemCount);
     _addMonitor.Pulse();
 }
コード例 #10
0
ファイル: DiskQueue.cs プロジェクト: nnikos123/dotNet-turbo
 /// <summary>
 /// Notifies about item addition
 /// </summary>
 private void NotifyItemAdded()
 {
     Interlocked.Increment(ref _itemCount);
     _takeMonitor.Pulse();
     _peekMonitor.PulseAll();
 }