public void TestsMultiThreading() { int MultiThreadAmount = Amount * 10; System.Threading.ManualResetEvent sharedResetEvent = new System.Threading.ManualResetEvent(false); int statLevelCountIn = 0; int stackLevelCountOut = 0; int product = ThreadCount * MultiThreadAmount; int enumerateCount = 0; //In these threads populate System.Threading.Thread[] pushThreads = new System.Threading.Thread[ThreadCount]; System.Threading.Thread[] popThreads = new System.Threading.Thread[ThreadCount]; System.Threading.Thread[] enumerateThreads = new System.Threading.Thread[ThreadCount]; Func <System.Threading.Thread> createEnumerateThread = () => { if (enumerateCount >= ThreadCount) { enumerateCount = 0; } return(enumerateThreads[enumerateCount] = new System.Threading.Thread(() => { try { long peek = 0; if (LinkedStack.TryPeek(ref peek)) { System.Console.WriteLine(System.Threading.Thread.CurrentThread.Name + "=> TryPeek: " + peek); System.Console.WriteLine(System.Threading.Thread.CurrentThread.Name + "=> Count" + LinkedStack.Count); } else if (false == LinkedStack.IsEmpty) { if (LinkedStack.TryPeek(ref peek)) { System.Console.WriteLine(System.Threading.Thread.CurrentThread.Name + "=> First = " + System.Threading.Thread.VolatileRead(ref LinkedStack.Last.Value)); } System.Console.WriteLine(System.Threading.Thread.CurrentThread.Name + "=> Last = " + System.Threading.Thread.VolatileRead(ref LinkedStack.Last.Value)); } } catch (Exception) { System.Console.WriteLine(System.Threading.Thread.CurrentThread.Name + " => Exception"); } }) { Name = "enumerateThreads" + enumerateCount++, ApartmentState = System.Threading.ApartmentState.MTA, Priority = System.Threading.ThreadPriority.AboveNormal }); }; for (int t = ThreadCount - 1; t >= 0; --t) { pushThreads[t] = new System.Threading.Thread(() => { int threadLocalCountIn = 0; while (threadLocalCountIn < MultiThreadAmount) { ++LastInputOutput; if (Common.Binary.IsEven(ref LastInputOutput) && LinkedStack.TryPush(ref LastInputOutput)) { System.Console.WriteLine(System.Threading.Thread.CurrentThread.Name + " @ TryPush => " + LastInputOutput); ++threadLocalCountIn; System.Threading.Interlocked.Increment(ref statLevelCountIn); sharedResetEvent.Set(); System.Threading.Thread.Yield(); } else { LinkedStack.Push(LastInputOutput); System.Console.WriteLine(System.Threading.Thread.CurrentThread.Name + " @ Push => " + LastInputOutput); ++threadLocalCountIn; System.Threading.Interlocked.Increment(ref statLevelCountIn); sharedResetEvent.Set(); System.Threading.Thread.Yield(); } } if (LinkedStack.IsEmpty) { System.Console.WriteLine("pushThread Empty"); } System.Console.WriteLine("pushThread Exit"); }) { ApartmentState = System.Threading.ApartmentState.MTA, Priority = System.Threading.ThreadPriority.Normal, Name = "pushThreads_" + t }; popThreads[t] = new System.Threading.Thread(() => { int threadLocalCountOut = 0; while (threadLocalCountOut < MultiThreadAmount) { long pop; if (LinkedStack.TryPop(out pop)) { ++threadLocalCountOut; System.Threading.Interlocked.Increment(ref stackLevelCountOut); System.Console.WriteLine(System.Threading.Thread.CurrentThread.Name + ": " + pop); //if(dequeue <= dequeueLast) throw new System.Exception("Unexpected value"); sharedResetEvent.Set(); System.Threading.Thread.Yield(); } } //if (false == LinkedStack.IsEmpty) throw new System.Exception("dequeueThread"); System.Console.WriteLine("popThread Exit"); }) { Priority = System.Threading.ThreadPriority.BelowNormal, ApartmentState = System.Threading.ApartmentState.MTA, Name = "popThreads_" + t }; enumerateThreads[t] = createEnumerateThread(); } System.Linq.ParallelEnumerable.ForAll(pushThreads.AsParallel(), t => t.Start()); System.Linq.ParallelEnumerable.ForAll(popThreads.AsParallel(), t => t.Start()); while (stackLevelCountOut == 0 && statLevelCountIn == 0) { sharedResetEvent.WaitOne(0); } while (stackLevelCountOut < product) { sharedResetEvent.Reset(); System.Console.WriteLine(System.Threading.Thread.CurrentThread.Name + "=> Count: " + LinkedStack.Count + "," + "CountIn: " + statLevelCountIn + "," + "CountOut: " + stackLevelCountOut); (enumerateThreads.FirstOrDefault(t => t.ThreadState == System.Threading.ThreadState.Unstarted) ?? createEnumerateThread()).Start(); sharedResetEvent.WaitOne(ThreadCount); } if (statLevelCountIn != stackLevelCountOut) { throw new System.Exception("count:" + statLevelCountIn + "," + stackLevelCountOut); } if (false == LinkedStack.IsEmpty) { throw new System.Exception("IsEmpty," + LinkedStack.Count); } System.Console.WriteLine("Count: " + LinkedStack.Count); }