public void TestUnlockWhenItemReceive() { int processed = 0; ManualResetEventSlim waiter = new ManualResetEventSlim(false); using (DelegateQueueAsyncProcessor <int> proc = new DelegateQueueAsyncProcessor <int>(Environment.ProcessorCount, 1000, "name", (elem, token) => { Interlocked.Increment(ref processed); waiter.Wait(token); })) { proc.Start(); for (int i = 0; i < proc.ThreadCount; i++) { proc.Add(i); } //if (!SpinWait.SpinUntil(() => Volatile.Read(ref processed) == proc.ThreadCount, 5000)) //{ // System.Diagnostics.Debugger.Launch(); // throw new Exception("Proc: " + Volatile.Read(ref processed).ToString() + ", threads: " + proc.ActiveThreadCount.ToString() + // ", tasks: " + proc.ElementCount.ToString()); //} TimingAssert.IsTrue(15000, () => Volatile.Read(ref processed) == proc.ThreadCount, "FAILED: wait for all thread start"); waiter.Set(); proc.Stop(true, true, true); Assert.IsTrue(proc.State == QueueAsyncProcessorState.Stopped, "proc.State == QueueAsyncProcessorState.Stopped"); } }
public void TestSimpleProcess() { int processed = 0; using (DelegateQueueAsyncProcessor <int> proc = new DelegateQueueAsyncProcessor <int>(Environment.ProcessorCount, 1000, "name", (elem, token) => { Interlocked.Increment(ref processed); })) { Assert.AreEqual(0, proc.ElementCount); Assert.AreEqual(Environment.ProcessorCount, proc.ThreadCount); Assert.AreEqual(false, proc.IsAddingCompleted); Assert.AreEqual(false, proc.IsBackground); Assert.AreEqual(false, proc.IsWork); Assert.AreEqual(1000, proc.QueueCapacity); Assert.IsTrue(proc.State == QueueAsyncProcessorState.Created); proc.Start(); Assert.IsTrue(proc.State == QueueAsyncProcessorState.Running); Assert.IsTrue(proc.IsWork); for (int i = 0; i < 10000; i++) { proc.Add(i); } proc.Stop(true, true, true); Assert.IsTrue(proc.State == QueueAsyncProcessorState.Stopped); Assert.IsFalse(proc.IsWork); Assert.AreEqual(10000, processed); } }
public void TestCantAddAfterDispose() { int processed = 0; using (DelegateQueueAsyncProcessor <int> proc = new DelegateQueueAsyncProcessor <int>(Environment.ProcessorCount, 1000, "name", (elem, token) => { Interlocked.Increment(ref processed); })) { Assert.IsTrue(proc.TryAdd(10)); proc.Start(); Assert.IsTrue(proc.TryAdd(20)); proc.Dispose(); proc.Add(-1); } }
public void TestHardStopWork() { int processed = 0; int startedTask = 0; ManualResetEventSlim waiter = new ManualResetEventSlim(false); using (DelegateQueueAsyncProcessor <int> proc = new DelegateQueueAsyncProcessor <int>(Environment.ProcessorCount, 1000, "name", (elem, token) => { try { Interlocked.Increment(ref startedTask); waiter.Wait(token); } finally { Interlocked.Increment(ref processed); } })) { proc.Start(); for (int i = 0; i < 5 * Environment.ProcessorCount; i++) { proc.Add(i); } Assert.IsTrue(proc.ThreadCount > 0, "proc.ThreadCount > 0"); Assert.IsTrue(proc.ThreadCount == Environment.ProcessorCount, "proc.ThreadCount == Environment.ProcessorCount"); TimingAssert.IsTrue(10000, () => proc.ActiveThreadCount >= 0, "FAILED: wait while thread activated"); TimingAssert.IsTrue(10000, () => proc.ActiveThreadCount == proc.ThreadCount, "FAILED: wait while all threads activated"); TimingAssert.IsTrue(10000, () => Volatile.Read(ref startedTask) >= 0, "FAILED: wait while first thread blocked"); TimingAssert.IsTrue(10000, () => Volatile.Read(ref startedTask) == proc.ThreadCount, () => "FAILED: wait while all thread blocked. Currently blocked = " + Volatile.Read(ref startedTask).ToString() + ", expected = " + proc.ThreadCount.ToString()); proc.Stop(true, false, true); Assert.IsTrue(proc.State == QueueAsyncProcessorState.Stopped, "proc.State == QueueAsyncProcessorState.Stopped"); Assert.IsTrue(processed > 0, "processed > 0"); } }
private void RunComplexTestOnCustom(int threadCount, int queueSize, int testElemCount, int addThreadCount, int procSpinWaitCount, int addSleepMs) { List <int> processedItems = new List <int>(testElemCount + 1); int currentItem = 0; Random rnd = new Random(); MemoryQueue <int> mem1 = new MemoryQueue <int>(100); MemoryQueue <int> mem2 = new MemoryQueue <int>(queueSize); LevelingQueue <int> lvl = new LevelingQueue <int>(mem1, mem2); using (DelegateQueueAsyncProcessor <int> proc = new DelegateQueueAsyncProcessor <int>(threadCount, lvl, "name", (elem, token) => { int curSpinCount = 0; lock (rnd) curSpinCount = rnd.Next(procSpinWaitCount); SpinWaitHelper.SpinWait(curSpinCount); lock (processedItems) processedItems.Add(elem); })) { Action addAction = () => { while (true) { int curVal = Interlocked.Increment(ref currentItem); if (curVal > testElemCount) { break; } proc.Add(curVal - 1); if (addSleepMs > 0) { SmartSleep(addSleepMs); } } }; Thread[] addThreads = new Thread[addThreadCount]; for (int i = 0; i < addThreads.Length; i++) { addThreads[i] = new Thread(new ThreadStart(addAction)); } for (int i = 0; i < addThreads.Length; i++) { addThreads[i].Start(); } proc.Start(); Assert.IsTrue(proc.IsWork); for (int i = 0; i < addThreads.Length; i++) { addThreads[i].Join(); } proc.Stop(true, true, true); Assert.AreEqual(testElemCount, processedItems.Count); processedItems.Sort(); for (int i = 0; i < processedItems.Count; i++) { Assert.AreEqual(i, processedItems[i]); } } }