Ejemplo n.º 1
0
        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);
        }