/// <summary> /// Деактивирует поток /// </summary> /// <param name="threadCountLowLimit">Минимальное число активных потоков</param> /// <returns>Успешность</returns> private bool DeactivateThread(int threadCountLowLimit) { if (GetActiveThreadCountFromCombination(Volatile.Read(ref _dieSlotActiveFullThreadCountCombination)) <= threadCountLowLimit) { return(false); } bool result = false; lock (_syncObject) { try { } finally { if (DecrementActiveThreadCount(threadCountLowLimit)) { _extThreadBlocker.AddExpectedWaiterCount(1); //Console.WriteLine("Thread deactivated = " + ActiveThreadCount.ToString()); result = true; } } } return(result); }
public void TestFullCycle() { PartialThreadBlocker inst = new PartialThreadBlocker(0); Barrier startBar = new Barrier(8 + 1); int exitedCount = 0; CancellationTokenSource tokenSrc = new CancellationTokenSource(); Thread[] threads = new Thread[8]; Func <int> sleepThCount = () => { int result = 0; foreach (var th in threads) { if ((th.ThreadState & ThreadState.WaitSleepJoin) != 0) { result++; } } return(result); }; for (int i = 0; i < threads.Length; i++) { threads[i] = new Thread(() => { startBar.SignalAndWait(); while (!tokenSrc.IsCancellationRequested) { inst.Wait(); SpinWaitHelper.SpinWait(1200); Thread.Yield(); } Interlocked.Increment(ref exitedCount); }); threads[i].Start(); } startBar.SignalAndWait(); for (int i = 0; i < threads.Length; i++) { TimingAssert.AreEqual(5000, i, sleepThCount, "UP. Sleeping thread count != i"); TimingAssert.AreEqual(5000, i, () => inst.RealWaiterCount, "UP. RealWaiterCount != i"); TimingAssert.AreEqual(5000, i, () => inst.ExpectedWaiterCount, "UP. ExpectedWaiterCount != i"); inst.AddExpectedWaiterCount(1); Thread.Sleep(10); } TimingAssert.AreEqual(5000, threads.Length, sleepThCount); TimingAssert.AreEqual(5000, threads.Length, () => inst.RealWaiterCount); TimingAssert.AreEqual(5000, threads.Length, () => inst.ExpectedWaiterCount); for (int i = threads.Length; i > 0; i--) { TimingAssert.AreEqual(5000, i, sleepThCount); TimingAssert.AreEqual(5000, i, () => inst.RealWaiterCount); TimingAssert.AreEqual(5000, i, () => inst.ExpectedWaiterCount); inst.SubstractExpectedWaiterCount(1); Thread.Sleep(10); } TimingAssert.AreEqual(5000, 0, sleepThCount, "Sleeping thread count != 0"); TimingAssert.AreEqual(5000, 0, () => inst.RealWaiterCount, "RealWaiterCount != 0"); TimingAssert.AreEqual(5000, 0, () => inst.ExpectedWaiterCount, "ExpectedWaiterCount != 0"); tokenSrc.Cancel(); TimingAssert.AreEqual(5000, threads.Length, () => Volatile.Read(ref exitedCount)); }