private static bool RunComplexTestOnBlockingCollection(int elemCount, int thCount) { BlockingCollection <ThreadPoolWorkItem> q = new BlockingCollection <ThreadPoolWorkItem>(1000); int mainIndex = -1; int trackElemCount = elemCount; int addFinished = 0; ThreadPoolLocalQueue[] locQ = new ThreadPoolLocalQueue[thCount]; for (int i = 0; i < locQ.Length; i++) { locQ[i] = new ThreadPoolLocalQueue(); } Thread[] threadsMain = new Thread[thCount]; Thread[] threadsAdditional = new Thread[thCount]; CancellationTokenSource tokSrc = new CancellationTokenSource(); List <int> global = new List <int>(elemCount); Action additionalAction = () => { while (true) { int item = Interlocked.Decrement(ref trackElemCount); if (item < 0) { break; } q.Add(new TestThreadPoolItem(item)); } Interlocked.Increment(ref addFinished); }; Action mainAction = () => { var localQ = locQ[Interlocked.Increment(ref mainIndex)]; List <int> data = new List <int>(); try { int index = 0; while (Volatile.Read(ref addFinished) < thCount) { ThreadPoolWorkItem tmp = null; if (q.TryTake(out tmp, -1, tokSrc.Token)) { data.Add((TestThreadPoolItem)tmp); } if (((index++) % 10) == 0) { int item = Interlocked.Decrement(ref trackElemCount); if (item >= 0) { while (!q.TryAdd(new TestThreadPoolItem(item))) { if (q.TryTake(out tmp, 0, CancellationToken.None)) { data.Add((TestThreadPoolItem)tmp); } } } } } } catch (OperationCanceledException) { } ThreadPoolWorkItem tmp2; while (q.TryTake(out tmp2)) { data.Add((TestThreadPoolItem)tmp2); } lock (global) global.AddRange(data); }; 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)); } Stopwatch sw = Stopwatch.StartNew(); 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(); } sw.Stop(); bool result = true; if (elemCount != global.Count) { Console.WriteLine("Incorrect items count"); result = false; } global.Sort(); for (int i = 0; i < Math.Min(elemCount, global.Count); i++) { if (global[i] != i) { Console.WriteLine("Incorrect items value"); result = false; break; } } Console.WriteLine(q.GetType().Name + ". Element count = " + elemCount.ToString() + ", Time = " + sw.ElapsedMilliseconds.ToString() + "ms"); Console.WriteLine(); return(result); }