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(); } }
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; } } } }
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); }
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); }
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()); } }
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)); } }
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(); } }
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(); } }
/// <summary> /// Notifies that item was taken /// </summary> private void NotifyItemTaken() { Interlocked.Decrement(ref _itemCount); _addMonitor.Pulse(); }
/// <summary> /// Notifies about item addition /// </summary> private void NotifyItemAdded() { Interlocked.Increment(ref _itemCount); _takeMonitor.Pulse(); _peekMonitor.PulseAll(); }