public void TestTakeLock() { ThreadPoolQueueController q = new ThreadPoolQueueController(100, 1000); bool takeCompleted = false; int takeItem = 0; int startedFlag = 0; Task.Run(() => { Interlocked.Exchange(ref startedFlag, 1); takeItem = (TestThreadPoolItem)q.Take(null); Volatile.Write(ref takeCompleted, true); }); TimingAssert.IsTrue(5000, () => Volatile.Read(ref startedFlag) == 1); Thread.Sleep(100); Assert.IsFalse(takeCompleted); q.Add(new TestThreadPoolItem(10), null); TimingAssert.IsTrue(5000, () => Volatile.Read(ref takeCompleted)); Assert.AreEqual(10, takeItem); Assert.AreEqual(0, q.GlobalQueue.OccupiedNodesCount); }
public void TestTakeBlocks() { PrioritizedElementsContainer <int> testInst = new PrioritizedElementsContainer <int>(new PoolElementComparer()); CancellationTokenSource tokSrc = new CancellationTokenSource(); bool wasCancelled = false; bool wasEntered = false; bool wasExited = false; Task.Run(() => { try { Volatile.Write(ref wasEntered, true); PoolElementWrapper <int> item; testInst.TryTake(out item, -1, tokSrc.Token); } catch (OperationCanceledException) { Volatile.Write(ref wasCancelled, true); } Volatile.Write(ref wasExited, true); }); TimingAssert.IsTrue(10000, () => Volatile.Read(ref wasEntered)); Thread.Sleep(100); Assert.IsFalse(Volatile.Read(ref wasExited)); tokSrc.Cancel(); TimingAssert.IsTrue(10000, () => Volatile.Read(ref wasExited)); Assert.IsTrue(Volatile.Read(ref wasCancelled)); }
public void TestCancellationOnStop() { int threadEnter = 0; int threadExit = 0; ManualResetEventSlim waiter = new ManualResetEventSlim(false); using (DelegateThreadSetManager testInst = new DelegateThreadSetManager(Environment.ProcessorCount, "name", (id, state, token) => { try { Interlocked.Increment(ref threadEnter); waiter.Wait(token); } finally { Interlocked.Increment(ref threadExit); } })) { testInst.Start(); TimingAssert.IsTrue(15000, () => testInst.State == ThreadSetManagerState.Running); TimingAssert.IsTrue(15000, () => testInst.ActiveThreadCount == Environment.ProcessorCount); TimingAssert.IsTrue(15000, () => Volatile.Read(ref threadEnter) == Environment.ProcessorCount); testInst.Stop(); Assert.IsTrue(testInst.State == ThreadSetManagerState.Stopped); Assert.AreEqual(0, testInst.ActiveThreadCount); Assert.AreEqual(Environment.ProcessorCount, threadExit, "threadExit != configurated thread count"); } }
public void TestSendOrPostCallbackSyncThreadPoolWorkItem() { int value = 0; System.Threading.SendOrPostCallback act = (s) => { Interlocked.Increment(ref value); }; var item = new SendOrPostCallbackSyncThreadPoolWorkItem(act, null); bool waitFinished = false; int startedFlag = 0; Task.Run(() => { Interlocked.Exchange(ref startedFlag, 1); item.Wait(); Volatile.Write(ref waitFinished, true); }); TimingAssert.IsTrue(5000, () => Volatile.Read(ref startedFlag) == 1); Thread.Sleep(100); Assert.AreEqual(0, value); Assert.AreEqual(false, waitFinished); item.Run(false, false); TimingAssert.AreEqual(5000, 1, () => Volatile.Read(ref value)); TimingAssert.AreEqual(5000, true, () => Volatile.Read(ref waitFinished)); }
public void TestSilentTakeCancellation() { ThreadPoolQueueController q = new ThreadPoolQueueController(100, 1000); CancellationTokenSource cSrc = new CancellationTokenSource(); bool takeCompleted = false; bool takeResult = false; ThreadPoolWorkItem takenItem = null; int startedFlag = 0; Task.Run(() => { Interlocked.Exchange(ref startedFlag, 1); var res = q.TryTake(null, out takenItem, -1, cSrc.Token, false); Volatile.Write(ref takeResult, res); Volatile.Write(ref takeCompleted, true); }); TimingAssert.IsTrue(5000, () => Volatile.Read(ref startedFlag) == 1); Thread.Sleep(100); Assert.IsFalse(takeCompleted); cSrc.Cancel(); TimingAssert.IsTrue(5000, () => Volatile.Read(ref takeCompleted)); Assert.IsFalse(takeResult); Assert.IsTrue(q.TryAdd(new TestThreadPoolItem(1), null, false, 0, CancellationToken.None)); Assert2.AreEqual(1, q.Take(null)); Assert.AreEqual(0, q.GlobalQueue.OccupiedNodesCount); Assert.AreEqual(100, q.GlobalQueue.FreeNodesCount); }
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 CaptureContextNoSyncContextTest() { var originalContext = SynchronizationContext.Current; var syncContext = new CustomSyncContext(); try { SynchronizationContext.SetSynchronizationContext(syncContext); var eContext = ExecutionContextHelper.CaptureContextNoSyncContextIfPossible(); Assert.IsNotNull(eContext); AtomicBool isDefaulContext = new AtomicBool(false); var task = Task.Run(() => { SynchronizationContext.SetSynchronizationContext(null); ExecutionContextHelper.RunInContext(eContext, (st) => { isDefaulContext.Value = SynchronizationContext.Current == null; }, null, true); }); task.Wait(); TimingAssert.IsTrue(10000, isDefaulContext, "Default context expected"); } finally { SynchronizationContext.SetSynchronizationContext(originalContext); } }
public void TestCancellation() { SemaphoreLight inst = new SemaphoreLight(0); CancellationTokenSource tokenSrc = new CancellationTokenSource(); bool cancelled = false; Task.Run(() => { try { inst.Wait(tokenSrc.Token); } catch (OperationCanceledException) { Volatile.Write(ref cancelled, true); Thread.MemoryBarrier(); } }); TimingAssert.IsTrue(5000, () => inst.WaiterCount > 0); Assert.IsFalse(Volatile.Read(ref cancelled)); tokenSrc.Cancel(); TimingAssert.IsTrue(5000, () => Volatile.Read(ref cancelled)); Assert.AreEqual(0, inst.CurrentCount); Assert.AreEqual(0, inst.WaiterCount); }
public void TestRunAndStopWithLongWork() { int threadExit = 0; using (DelegateThreadSetManager testInst = new DelegateThreadSetManager(Environment.ProcessorCount, "name", (id, state, token) => { Thread.Sleep(2500); Interlocked.Increment(ref threadExit); })) { Assert.IsTrue(testInst.State == ThreadSetManagerState.Created); Assert.AreEqual(Environment.ProcessorCount, testInst.ThreadCount); Assert.IsFalse(testInst.IsWork); testInst.Start(); TimingAssert.IsTrue(15000, () => testInst.ActiveThreadCount == Environment.ProcessorCount); testInst.Stop(); Assert.IsTrue(testInst.State == ThreadSetManagerState.Stopped); Assert.AreEqual(0, testInst.ActiveThreadCount); Assert.AreEqual(Environment.ProcessorCount, threadExit); } }
public void TestSimpleRunAndStop() { int threadStart = 0; using (DelegateThreadSetManager testInst = new DelegateThreadSetManager(Environment.ProcessorCount, "name", (id, state, token) => { Interlocked.Increment(ref threadStart); })) { Assert.IsTrue(testInst.State == ThreadSetManagerState.Created, "State != Created"); Assert.AreEqual(Environment.ProcessorCount, testInst.ThreadCount); Assert.IsFalse(testInst.IsWork); testInst.Start(); SpinWait.SpinUntil(() => Volatile.Read(ref threadStart) >= testInst.ThreadCount, 10000); TestContext.WriteLine("All thread started"); bool byCondition = SpinWait.SpinUntil(() => testInst.ActiveThreadCount == 0, 5000); TestContext.WriteLine(byCondition ? "ActiveThreadCount == 0" : "ActiveThreadCount != 0 (timeout)"); TimingAssert.AreEqual(15000, Environment.ProcessorCount, () => Volatile.Read(ref threadStart)); TimingAssert.IsTrue(5000, () => testInst.State == ThreadSetManagerState.AllThreadsExited, "State != AllThreadsExited"); testInst.Stop(); Assert.IsTrue(testInst.State == ThreadSetManagerState.Stopped, "State != Stopped"); } }
private void RunComplexTest() { using (EntryCountingEvent inst = new EntryCountingEvent()) { Barrier bar = new Barrier(7); int threadFinished = 0; int entryCount = 0; bool isTestDispose = false; List <Task> taskList = new List <Task>(); for (int i = 0; i < 6; i++) { int a = i; var task = Task.Run(() => { Random rnd = new Random(a); bar.SignalAndWait(); for (int j = 0; j < 1000; j++) { using (var eee = inst.TryEnter()) { if (!eee.IsAcquired) { break; } Interlocked.Increment(ref entryCount); if (isTestDispose) { throw new Exception(); } Thread.Sleep(rnd.Next(10, 100)); if (isTestDispose) { throw new Exception(); } } } Interlocked.Increment(ref threadFinished); }); taskList.Add(task); } bar.SignalAndWait(); TimingAssert.IsTrue(5000, () => Volatile.Read(ref entryCount) > 12); inst.TerminateAndWait(); isTestDispose = true; inst.Dispose(); TimingAssert.AreEqual(5000, 6, () => Volatile.Read(ref threadFinished)); Task.WhenAll(taskList); } }
public void TestExtensionWork() { ThreadPoolQueueController q = new ThreadPoolQueueController(100, 1000); Assert.AreEqual(100, q.GlobalQueue.ExtendedCapacity); for (int i = 0; i < 100; i++) { q.Add(new TestThreadPoolItem(i), null); } bool addCompleted = false; int startedFlag = 0; Task.Run(() => { Interlocked.Exchange(ref startedFlag, 1); q.Add(new TestThreadPoolItem(100), null); Volatile.Write(ref addCompleted, true); }); TimingAssert.IsTrue(5000, () => Volatile.Read(ref startedFlag) == 1); Thread.Sleep(100); Assert.IsFalse(addCompleted); q.ExtendGlobalQueueCapacity(100); TimingAssert.IsTrue(5000, () => Volatile.Read(ref addCompleted)); Assert.AreEqual(200, q.GlobalQueue.ExtendedCapacity); for (int i = 101; i < 200; i++) { Assert.IsTrue(q.TryAdd(new TestThreadPoolItem(i), null, false, 0, CancellationToken.None)); } Assert.IsFalse(q.TryAdd(new TestThreadPoolItem(int.MaxValue), null, false, 0, CancellationToken.None)); for (int i = 0; i < 200; i++) { Assert2.AreEqual(i, q.Take(null)); } Assert.AreEqual(0, q.GlobalQueue.OccupiedNodesCount); Assert.AreEqual(100, q.GlobalQueue.ExtendedCapacity); Assert.AreEqual(100, q.GlobalQueue.FreeNodesCount); }
public void TestTaskSchedulerSetted() { using (DynamicThreadPool testInst = new DynamicThreadPool(0, Environment.ProcessorCount, -1, "name", false, new DynamicThreadPoolOptions() { UseOwnTaskScheduler = true, UseOwnSyncContext = true })) { AtomicBool isPropperSceduller = new AtomicBool(false); testInst.Run(() => { isPropperSceduller.Value = TaskScheduler.Current == testInst.TaskScheduler; }); TimingAssert.IsTrue(10000, isPropperSceduller, "isPropperSceduller"); testInst.Dispose(true, true, false); } }
public void TestIncreaseWaiters() { PartialThreadBlocker inst = new PartialThreadBlocker(4); Barrier startBar = new Barrier(8 + 1); int exitedCount = 0; int somethingWork = 0; CancellationTokenSource tokenSrc = new CancellationTokenSource(); for (int i = 0; i < 8; i++) { Task.Run(() => { startBar.SignalAndWait(); while (!tokenSrc.IsCancellationRequested) { inst.Wait(); Interlocked.Increment(ref somethingWork); Thread.Sleep(10); } Interlocked.Increment(ref exitedCount); }); } startBar.SignalAndWait(); TimingAssert.AreEqual(5000, 4, () => inst.ExpectedWaiterCount); TimingAssert.AreEqual(5000, 4, () => inst.RealWaiterCount, "Real waiter count != 4 (can be caused by slow processing)"); TimingAssert.IsTrue(5000, () => Volatile.Read(ref somethingWork) > 0); inst.SetExpectedWaiterCount(8); Assert.AreEqual(8, inst.ExpectedWaiterCount); TimingAssert.AreEqual(5000, 8, () => inst.RealWaiterCount); Interlocked.Exchange(ref somethingWork, 0); TimingAssert.IsTrue(5000, () => Volatile.Read(ref somethingWork) == 0); tokenSrc.Cancel(); inst.SetExpectedWaiterCount(0); TimingAssert.AreEqual(5000, 8, () => Volatile.Read(ref exitedCount)); TimingAssert.AreEqual(5000, 0, () => inst.ExpectedWaiterCount); TimingAssert.AreEqual(500, 0, () => inst.RealWaiterCount); }
public void TestAddCancellation() { ThreadPoolQueueController q = new ThreadPoolQueueController(100, 1000); CancellationTokenSource cSrc = new CancellationTokenSource(); for (int i = 0; i < 100; i++) { q.Add(new TestThreadPoolItem(i), null); } bool addCompleted = false; int startedFlag = 0; Task.Run(() => { try { Interlocked.Exchange(ref startedFlag, 1); q.TryAdd(new TestThreadPoolItem(int.MaxValue), null, false, -1, cSrc.Token); } catch (OperationCanceledException) { } Volatile.Write(ref addCompleted, true); }); TimingAssert.IsTrue(5000, () => Volatile.Read(ref startedFlag) == 1); Thread.Sleep(100); Assert.IsFalse(addCompleted); cSrc.Cancel(); TimingAssert.IsTrue(5000, () => Volatile.Read(ref addCompleted)); for (int i = 0; i < 100; i++) { Assert2.AreEqual(i, q.Take(null)); } Assert.AreEqual(0, q.GlobalQueue.OccupiedNodesCount); Assert.AreEqual(100, q.GlobalQueue.FreeNodesCount); }
public void TestRegisterDeregister() { int calledCount = 0; ManagementThreadControllerCallback act = (elapsed) => { Interlocked.Increment(ref calledCount); return(true); }; ManagementThreadController.Instance.RegisterCallback(act); TimingAssert.IsTrue(10 * ManagementThreadController.SleepPeriod, () => Volatile.Read(ref calledCount) > 0); ManagementThreadController.Instance.UnregisterCallback(act); int lastCallCount = calledCount; TimingAssert.AreEqual(2 * ManagementThreadController.SleepPeriod, lastCallCount, () => Volatile.Read(ref calledCount)); }
public void TestWakeUpOnRelease() { SemaphoreLight inst = new SemaphoreLight(0); bool wakeUp = false; Task.Run(() => { inst.Wait(); wakeUp = true; }); TimingAssert.IsTrue(5000, () => inst.WaiterCount > 0); Assert.IsFalse(wakeUp); inst.Release(); TimingAssert.IsTrue(5000, () => Volatile.Read(ref wakeUp)); Assert.AreEqual(0, inst.CurrentCount); Assert.AreEqual(0, inst.WaiterCount); }
public void SetTaskSchedulerAndExecuteEntryTest() { var sched = new TestTaskScheduler(); int val = 0; AtomicBool taskSchedullerSetted = new AtomicBool(false); Task tsk = null; tsk = new Task(() => { taskSchedullerSetted.Value = TaskScheduler.Current == sched; Interlocked.Increment(ref val); }); TaskHelper.SetTaskScheduler(tsk, sched); TaskHelper.ExecuteTaskEntry(tsk); TimingAssert.IsTrue(10000, taskSchedullerSetted, "taskSchedullerSetted"); }
public void TestTerminateWaiting() { using (EntryCountingEvent inst = new EntryCountingEvent()) { bool finished = false; Task task = null; using (inst.Enter()) { task = Task.Run(() => { inst.TerminateAndWait(); finished = true; }); TimingAssert.IsFalse(5000, () => finished); } TimingAssert.IsTrue(5000, () => finished); task.Wait(); } }
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"); } }
public void TestPeekWait() { BlockingQueue <int> col = new BlockingQueue <int>(100); int startedFlag = 0; int peekVal = 0; Task.Run(() => { Interlocked.Exchange(ref startedFlag, 1); peekVal = col.Peek(); }); TimingAssert.IsTrue(5000, () => Volatile.Read(ref startedFlag) == 1); Thread.Sleep(100); Assert.AreEqual(0, peekVal); col.Add(100); TimingAssert.AreEqual(5000, 100, () => Volatile.Read(ref peekVal)); TimingAssert.AreEqual(5000, 1, () => col.Count); }
public void TestTimeoutWork() { PartialThreadBlocker inst = new PartialThreadBlocker(4); int exitedCount = 0; bool exitByTimeout = false; Task.Run(() => { Volatile.Write(ref exitByTimeout, !inst.Wait(1500)); Interlocked.Increment(ref exitedCount); }); TimingAssert.AreEqual(5000, 4, () => inst.ExpectedWaiterCount); TimingAssert.AreEqual(5000, 1, () => inst.RealWaiterCount); TimingAssert.AreEqual(5000, 4, () => inst.ExpectedWaiterCount); TimingAssert.AreEqual(5000, 0, () => inst.RealWaiterCount); TimingAssert.AreEqual(5000, 1, () => Volatile.Read(ref exitedCount)); TimingAssert.IsTrue(5000, () => Volatile.Read(ref exitByTimeout)); }
public void RegisterWithoutECTest() { var originalContext = SynchronizationContext.Current; var syncContext = new CustomSyncContext(); try { CancellationTokenSource tokenSource = new CancellationTokenSource(); CancellationToken token = tokenSource.Token; AtomicBool isNoExecutionContext = new AtomicBool(false); using (CancellationTokenHelper.RegisterWithoutECIfPossible(token, (st) => { isNoExecutionContext.Value = SynchronizationContext.Current == null; }, null)) { Barrier barrier = new Barrier(2); Barrier barrier2 = new Barrier(2); Task.Run(() => { barrier.SignalAndWait(); barrier2.SignalAndWait(); tokenSource.Cancel(); }); barrier.SignalAndWait(); SynchronizationContext.SetSynchronizationContext(syncContext); barrier2.SignalAndWait(); TimingAssert.IsTrue(10000, isNoExecutionContext, "isNoExecutionContext"); } } finally { SynchronizationContext.SetSynchronizationContext(originalContext); } }
public void TestAddLock() { ThreadPoolGlobalQueue q = new ThreadPoolGlobalQueue(100); for (int i = 0; i < 100; i++) { q.Add(new TestThreadPoolItem(i)); } bool addCompleted = false; int startedFlag = 0; Task.Run(() => { Interlocked.Exchange(ref startedFlag, 1); q.Add(new TestThreadPoolItem(int.MaxValue)); Volatile.Write(ref addCompleted, true); }); TimingAssert.IsTrue(10000, () => Volatile.Read(ref startedFlag) == 1); Thread.Sleep(100); Assert.IsFalse(addCompleted); Assert2.AreEqual(0, q.Take()); TimingAssert.IsTrue(5000, () => Volatile.Read(ref addCompleted)); Assert.IsFalse(q.TryAdd(new TestThreadPoolItem(int.MinValue), 0, CancellationToken.None)); for (int i = 1; i < 100; i++) { Assert2.AreEqual(i, (TestThreadPoolItem)q.Take(), "(TestThreadPoolItem)q.Take(null, null) == i"); } Assert2.AreEqual(int.MaxValue, q.Take(), "(TestThreadPoolItem)q.Take(null, null) == int.MaxValue"); Assert.AreEqual(0, q.OccupiedNodesCount); }
public void TestSyncContextSetted() { using (DynamicThreadPool testInst = new DynamicThreadPool(0, Environment.ProcessorCount, -1, "name", false, new DynamicThreadPoolOptions() { UseOwnTaskScheduler = true, UseOwnSyncContext = true })) { AtomicBool isPropperSyncContext = new AtomicBool(false); testInst.Run(() => { if (SynchronizationContext.Current != null) { SynchronizationContext.Current.Post((st) => { isPropperSyncContext.Value = testInst.IsThreadPoolThread; }, null); } }); TimingAssert.IsTrue(10000, isPropperSyncContext, "isPropperSyncContext"); testInst.Dispose(true, true, false); } }
public void TestNoSyncContextAndTaskSchedullerWhenNotConfigurated() { using (DynamicThreadPool testInst = new DynamicThreadPool(0, Environment.ProcessorCount, -1, "name", false, new DynamicThreadPoolOptions() { UseOwnTaskScheduler = false, UseOwnSyncContext = false })) { var defSyncContext = SynchronizationContext.Current; var defTaskScheduller = TaskScheduler.Current; AtomicBool isDefaultSyncContext = new AtomicBool(false); AtomicBool isDefaultTaskScheduller = new AtomicBool(false); testInst.Run(() => { isDefaultSyncContext.Value = SynchronizationContext.Current == defSyncContext; isDefaultTaskScheduller.Value = TaskScheduler.Current == defTaskScheduller; }); TimingAssert.IsTrue(10000, isDefaultSyncContext, "isDefaultSyncContext"); TimingAssert.IsTrue(10000, isDefaultTaskScheduller, "isDefaultTaskScheduller"); testInst.Dispose(true, true, false); } }
public void TestCycledBlockRequiredCount() { PartialThreadBlocker inst = new PartialThreadBlocker(4); Barrier startBar = new Barrier(8 + 1); int exitedCount = 0; int somethingWork = 0; CancellationTokenSource tokenSrc = new CancellationTokenSource(); for (int i = 0; i < 8; i++) { Task.Run(() => { startBar.SignalAndWait(); while (!tokenSrc.IsCancellationRequested) { inst.Wait(); Interlocked.Increment(ref somethingWork); Thread.Sleep(10); } Interlocked.Increment(ref exitedCount); }); } startBar.SignalAndWait(); TimingAssert.AreEqual(5000, 4, () => inst.ExpectedWaiterCount); TimingAssert.AreEqual(5000, 4, () => inst.RealWaiterCount); TimingAssert.IsTrue(5000, () => Volatile.Read(ref somethingWork) > 0); tokenSrc.Cancel(); inst.SetExpectedWaiterCount(0); TimingAssert.AreEqual(5000, 8, () => Volatile.Read(ref exitedCount)); TimingAssert.AreEqual(5000, 0, () => inst.ExpectedWaiterCount); TimingAssert.AreEqual(5000, 0, () => inst.RealWaiterCount); }
public void TestTakeCancellation() { ThreadPoolGlobalQueue q = new ThreadPoolGlobalQueue(100); CancellationTokenSource cSrc = new CancellationTokenSource(); bool takeCompleted = false; ThreadPoolWorkItem takenItem = null; int startedFlag = 0; Task.Run(() => { try { Interlocked.Exchange(ref startedFlag, 1); q.TryTake(out takenItem, -1, cSrc.Token, true); } catch (OperationCanceledException) { } Volatile.Write(ref takeCompleted, true); }); TimingAssert.IsTrue(5000, () => Volatile.Read(ref startedFlag) == 1); Thread.Sleep(100); Assert.IsFalse(takeCompleted); cSrc.Cancel(); TimingAssert.IsTrue(5000, () => Volatile.Read(ref takeCompleted)); Assert.IsTrue(q.TryAdd(new TestThreadPoolItem(1), 0, CancellationToken.None)); Assert2.AreEqual(1, q.Take()); Assert.AreEqual(0, q.OccupiedNodesCount); Assert.AreEqual(100, q.FreeNodesCount); }
public void DynamicThreadPoolPerformBalancing() { using (DynamicThreadPool testInst = new DynamicThreadPool(0, 4 * Environment.ProcessorCount, 1000, "name")) { Assert.AreEqual(0, testInst.ActiveThreadCount); // ========== Проверяем, что число потоков увеличивается автоматически от нуля =========== int executedTaskCount = 0; for (int i = 0; i < 1000; i++) { testInst.Run(() => { Interlocked.Increment(ref executedTaskCount); }); } TimingAssert.AreEqual(5000, 1000, () => Volatile.Read(ref executedTaskCount)); Assert.IsTrue(testInst.ActiveThreadCount > 0, "1. testInst.ActiveThreadCount > 0"); // ======== Проверяем, что на большом числе задач он рано или поздно дойдёт до числа потоков равного числу ядер =========== executedTaskCount = 0; for (int i = 0; i < testInst.MaxThreadCount * testInst.QueueCapacity; i++) { testInst.Run(() => { Thread.Sleep(1); Interlocked.Increment(ref executedTaskCount); }); } TimingAssert.AreEqual(15000, testInst.MaxThreadCount * testInst.QueueCapacity, () => Volatile.Read(ref executedTaskCount)); Assert.IsTrue(testInst.ActiveThreadCount >= Environment.ProcessorCount, "2. testInst.ActiveThreadCount >= Environment.ProcessorCount"); // ======== Проверяем, что на долгих задачах число потоков может стать больше числа ядер =========== executedTaskCount = 0; for (int i = 0; i < 1000; i++) { testInst.Run(() => { Thread.Sleep(20); Interlocked.Increment(ref executedTaskCount); }); } TimingAssert.IsTrue(30000, () => Volatile.Read(ref executedTaskCount) >= 500); Assert.IsTrue(testInst.ActiveThreadCount > Environment.ProcessorCount, "3. testInst.ActiveThreadCount > Environment.ProcessorCount"); Assert.IsTrue(testInst.ActiveThreadCount <= testInst.MaxThreadCount, "3. testInst.ActiveThreadCount <= testInst.MaxThreadCount"); TimingAssert.AreEqual(30000, 1000, () => Volatile.Read(ref executedTaskCount)); TimingAssert.IsTrue(5000, () => testInst.ActiveThreadCount <= Environment.ProcessorCount, "4. testInst.ActiveThreadCount <= Environment.ProcessorCount"); } }