public void TestIsEmpty() { ThreadPoolConcurrentQueue q = new ThreadPoolConcurrentQueue(); Assert.IsTrue(q.IsEmpty); for (int i = 0; i < 10000; i++) { q.Add(new TestThreadPoolItem(i)); Assert.IsFalse(q.IsEmpty); } for (int i = 0; i < 10000; i++) { Assert.IsFalse(q.IsEmpty); ThreadPoolWorkItem res = null; Assert.IsTrue(q.TryTake(out res)); } Assert.IsTrue(q.IsEmpty); ThreadPoolWorkItem tmp = null; Assert.IsFalse(q.TryTake(out tmp)); Assert.IsNull(tmp); Assert.IsTrue(q.IsEmpty); }
public void ConcurrentTest() { ThreadPoolConcurrentQueue q = new ThreadPoolConcurrentQueue(); for (int i = 0; i < 5; i++) { RunThreadPoolConcurrentQueueTest(q, 300000, Math.Max(Environment.ProcessorCount / 2, 1)); } }
public void TestSingleAddTake() { ThreadPoolConcurrentQueue q = new ThreadPoolConcurrentQueue(); q.Add(new TestThreadPoolItem(10)); ThreadPoolWorkItem res = null; Assert.IsTrue(q.TryTake(out res)); Assert.IsNotNull(res); Assert2.AreEqual(10, res); }
public void TestManyAddTake() { ThreadPoolConcurrentQueue q = new ThreadPoolConcurrentQueue(); for (int i = 0; i < 100000; i++) { q.Add(new TestThreadPoolItem(i)); } for (int i = 0; i < 100000; i++) { ThreadPoolWorkItem res = null; Assert.IsTrue(q.TryTake(out res)); Assert.IsNotNull(res); Assert2.AreEqual(i, res); } }
private void RunThreadPoolConcurrentQueueTest(ThreadPoolConcurrentQueue q, int elemCount, int thCount) { int atomicRandom = 0; int trackElemCount = elemCount; int addFinished = 0; Thread[] threadsAdd = new Thread[thCount]; Thread[] threadsRemove = new Thread[thCount]; List <int> global = new List <int>(elemCount); Action addAction = () => { 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(1000); if (sleepTime > 0) { Thread.SpinWait(sleepTime); } } Interlocked.Increment(ref addFinished); }; Action removeAction = () => { Random rnd = new Random(Environment.TickCount + Interlocked.Increment(ref atomicRandom) * thCount * 2); List <int> data = new List <int>(); while (Volatile.Read(ref addFinished) < thCount) { ThreadPoolWorkItem tmp; if (q.TryTake(out tmp)) { data.Add((TestThreadPoolItem)tmp); } int sleepTime = rnd.Next(1000); if (sleepTime > 0) { Thread.SpinWait(sleepTime); } } ThreadPoolWorkItem tmp2; while (q.TryTake(out tmp2)) { data.Add((TestThreadPoolItem)tmp2); } lock (global) global.AddRange(data); }; for (int i = 0; i < threadsAdd.Length; i++) { threadsAdd[i] = new Thread(new ThreadStart(addAction)); } for (int i = 0; i < threadsRemove.Length; i++) { threadsRemove[i] = new Thread(new ThreadStart(removeAction)); } for (int i = 0; i < threadsAdd.Length; i++) { threadsAdd[i].Start(); } for (int i = 0; i < threadsRemove.Length; i++) { threadsRemove[i].Start(); } for (int i = 0; i < threadsAdd.Length; i++) { threadsAdd[i].Join(); } for (int i = 0; i < threadsRemove.Length; i++) { threadsRemove[i].Join(); } Assert.AreEqual(elemCount, global.Count); global.Sort(); for (int i = 0; i < elemCount; i++) { Assert.AreEqual(i, global[i]); } }
private static bool TestThreadPoolConcurrentQueue(int elemCount, int thCount, bool useRandom) { ThreadPoolConcurrentQueue q = new ThreadPoolConcurrentQueue(); int atomicRandom = 0; int trackElemCount = elemCount; int addFinished = 0; Thread[] threadsAdd = new Thread[thCount]; Thread[] threadsRemove = new Thread[thCount]; List <int> global = new List <int>(elemCount); Action addAction = () => { Random rnd = null; if (useRandom) { 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 = 0; if (rnd != null) { sleepTime = rnd.Next(elemCount / 10000) - elemCount / 10000 + 2; } if (sleepTime > 0) { Thread.Sleep(sleepTime); } } Interlocked.Increment(ref addFinished); }; Action removeAction = () => { Random rnd = null; if (useRandom) { rnd = new Random(Environment.TickCount + Interlocked.Increment(ref atomicRandom) * thCount * 2); } List <int> data = new List <int>(); while (Volatile.Read(ref addFinished) < thCount) { ThreadPoolWorkItem tmp; if (q.TryTake(out tmp)) { data.Add((TestThreadPoolItem)tmp); } int sleepTime = 0; if (rnd != null) { sleepTime = rnd.Next(elemCount / 10000) - elemCount / 10000 + 2; } if (sleepTime > 0) { Thread.Sleep(sleepTime); } } ThreadPoolWorkItem tmp2; while (q.TryTake(out tmp2)) { data.Add((TestThreadPoolItem)tmp2); } lock (global) global.AddRange(data); }; for (int i = 0; i < threadsAdd.Length; i++) { threadsAdd[i] = new Thread(new ThreadStart(addAction)); } for (int i = 0; i < threadsRemove.Length; i++) { threadsRemove[i] = new Thread(new ThreadStart(removeAction)); } Stopwatch sw = Stopwatch.StartNew(); for (int i = 0; i < threadsAdd.Length; i++) { threadsAdd[i].Start(); } for (int i = 0; i < threadsRemove.Length; i++) { threadsRemove[i].Start(); } for (int i = 0; i < threadsAdd.Length; i++) { threadsAdd[i].Join(); } for (int i = 0; i < threadsRemove.Length; i++) { threadsRemove[i].Join(); } sw.Stop(); bool result = true; global.Sort(); if (global.Count != elemCount) { result = false; Console.WriteLine("Incorrect element count"); } HashSet <int> set = new HashSet <int>(global); if (set.Count != global.Count) { result = false; Console.WriteLine("Incorrect distinct element count"); } for (int i = 0; i < Math.Min(elemCount, global.Count); i++) { if (global[i] != i) { result = false; Console.WriteLine("Incorrect data"); break; } } Console.WriteLine(q.GetType().Name + ". Element count = " + elemCount.ToString() + ", Time = " + sw.ElapsedMilliseconds.ToString() + "ms"); Console.WriteLine(); return(result); }