public void TestSilentTakeCancellation() { ThreadPoolGlobalQueue q = new ThreadPoolGlobalQueue(100); CancellationTokenSource cSrc = new CancellationTokenSource(); bool takeCompleted = false; bool takeResult = false; ThreadPoolWorkItem takenItem = null; int startedFlag = 0; Task.Run(() => { Interlocked.Exchange(ref startedFlag, 1); var res = q.TryTake(out takenItem, -1, cSrc.Token, false); Volatile.Write(ref takeResult, res); Volatile.Write(ref takeCompleted, true); }); TimingAssert.IsTrue(5000, () => Volatile.Read(ref startedFlag) == 1); Thread.Sleep(100); Assert.IsFalse(takeCompleted); cSrc.Cancel(); TimingAssert.IsTrue(5000, () => Volatile.Read(ref takeCompleted)); Assert.IsFalse(takeResult); Assert.IsTrue(q.TryAdd(new TestThreadPoolItem(1), 0, CancellationToken.None)); Assert2.AreEqual(1, q.Take()); Assert.AreEqual(0, q.OccupiedNodesCount); Assert.AreEqual(100, q.FreeNodesCount); }
public void TestSimpleAddTake() { ThreadPoolGlobalQueue q = new ThreadPoolGlobalQueue(100); Assert.IsTrue(q.TryAdd(new TestThreadPoolItem(10), 0, CancellationToken.None)); ThreadPoolWorkItem res = null; Assert.IsTrue(q.TryTake(out res, 0, CancellationToken.None, true)); Assert2.AreEqual(10, res); }
public void TestManyAddTake() { ThreadPoolGlobalQueue q = new ThreadPoolGlobalQueue(100); for (int i = 0; i < 100; i++) { Assert.IsTrue(q.TryAdd(new TestThreadPoolItem(i), 0, CancellationToken.None)); } Assert.IsFalse(q.TryAdd(new TestThreadPoolItem(int.MaxValue), 0, CancellationToken.None)); for (int i = 0; i < 100; i++) { ThreadPoolWorkItem res = null; Assert.IsTrue(q.TryTake(out res, 0, CancellationToken.None, true)); Assert2.AreEqual(i, res, "(TestThreadPoolItem)res == i"); } ThreadPoolWorkItem tmp = null; Assert.IsFalse(q.TryTake(out tmp, 0, CancellationToken.None, true)); }
private void RunComplexTest(ThreadPoolGlobalQueue q, int elemCount, int thCount) { int atomicRandom = 0; int trackElemCount = elemCount; int addFinished = 0; Thread[] threadsMain = new Thread[thCount]; Thread[] threadsAdditional = new Thread[thCount]; CancellationTokenSource tokSrc = new CancellationTokenSource(); List <int> global = new List <int>(elemCount); Action additionalAction = () => { Random rnd = new Random(Environment.TickCount + Interlocked.Increment(ref atomicRandom) * thCount * 2); while (true) { int item = Interlocked.Decrement(ref trackElemCount); if (item < 0) { break; } q.Add(new TestThreadPoolItem(item)); int sleepTime = rnd.Next(120); if (sleepTime > 0) { SpinWaitHelper.SpinWait(sleepTime); } if (rnd.Next(100) == 0) { q.RequestCapacityExtension(50); } } Interlocked.Increment(ref addFinished); }; Action mainAction = () => { Random rnd = new Random(Environment.TickCount + Interlocked.Increment(ref atomicRandom) * thCount * 2); List <int> data = new List <int>(); try { while (Volatile.Read(ref addFinished) < thCount) { ThreadPoolWorkItem tmp = null; if (q.TryTake(out tmp, -1, tokSrc.Token, true)) { data.Add((TestThreadPoolItem)tmp); } int sleepTime = rnd.Next(100); if (sleepTime > 0) { SpinWaitHelper.SpinWait(sleepTime); } } } catch (OperationCanceledException) { } ThreadPoolWorkItem tmp2; while (q.TryTake(out tmp2, 0, CancellationToken.None, true)) { data.Add((TestThreadPoolItem)tmp2); } lock (global) global.AddRange(data); }; Task.Delay(1000).ContinueWith(t => q.RequestCapacityExtension(50)); for (int i = 0; i < threadsMain.Length; i++) { threadsMain[i] = new Thread(new ThreadStart(mainAction)); } for (int i = 0; i < threadsAdditional.Length; i++) { threadsAdditional[i] = new Thread(new ThreadStart(additionalAction)); } for (int i = 0; i < threadsMain.Length; i++) { threadsMain[i].Start(); } for (int i = 0; i < threadsAdditional.Length; i++) { threadsAdditional[i].Start(); } for (int i = 0; i < threadsAdditional.Length; i++) { threadsAdditional[i].Join(); } tokSrc.Cancel(); for (int i = 0; i < threadsMain.Length; i++) { threadsMain[i].Join(); } Assert.AreEqual(elemCount, global.Count); global.Sort(); for (int i = 0; i < elemCount; i++) { Assert.AreEqual(i, global[i]); } }