public void TestNoBlock() { BlockingThreadPool threadPool = new BlockingThreadPool(2, 2); MessageLog log = new MessageLog(); for (int i = 0; i < TestIterationsCount; i++) { log.Clear(); Assert.That(threadPool.Execute(() => { log.Log("task 1: started"); // T = 0 Thread.Sleep(200); log.Log("task 1: finished"); // T = 200 }, 100), Is.True); Thread.Sleep(50); // T = 50 Assert.That(threadPool.Execute(() => { log.Log("task 2: started"); // T = 50 Thread.Sleep(200); log.Log("task 2: finished"); // T = 250 }, 100), Is.True); Thread.Sleep(50); log.Log("main: wait started"); // T = 100 Thread.Sleep(200); log.Log("main: wait finished"); // T = 300 Assert.That(log.GetLog(), Is.EqualTo(new string[] { "task 1: started", "task 2: started", "main: wait started", "task 1: finished", "task 2: finished", "main: wait finished" })); } Assert.That(threadPool.Stop(1000), Is.True); }
private void Start() { VersionMessage outVersionMessage = CreateVersionMessage(); WriteMessage(outVersionMessage); BitcoinMessage incVersionMessage = conn.ReadMessage(); if (incVersionMessage.Command != VersionMessage.Command) { throw new BitcoinNetworkException("Remote endpoint did not send Version message."); } VersionMessage incVersionMessageParsed; using (BitcoinStreamReader reader = new BitcoinStreamReader(new MemoryStream(incVersionMessage.Payload))) { //todo: review and handle exceptions incVersionMessageParsed = VersionMessage.Read(reader); } //todo: check minimal peer protocol version WriteMessage(new VerAckMessage()); BitcoinMessage incVerAckMessage = conn.ReadMessage(); if (incVerAckMessage.Command != VerAckMessage.Command) { //todo: handle correctly throw new BitcoinNetworkException("Remote endpoint did not send VerAck message."); } peerInfo = new BitcoinPeerInfo(conn.RemoteEndPoint, incVersionMessageParsed); running = true; threadPool = new BlockingThreadPool(MessageProcessingThreadsCount, MessageProcessingTasksCount); listenerThread = new Thread(Listen); listenerThread.Name = "Endpoint Listener"; listenerThread.IsBackground = true; //todo: ??? should it be background? listenerThread.Start(); }
public void WarmUp() { //the first thread creation can take considerable time Stopwatch sw = Stopwatch.StartNew(); AutoResetEvent ev = new AutoResetEvent(false); BlockingThreadPool threadPool = new BlockingThreadPool(1, 1); Assume.That(threadPool.Execute(() => ev.Set(), 100), Is.True); ev.WaitOne(); Assert.That(threadPool.Stop(1000), Is.True); Console.WriteLine("WarmUp: {0}ms", sw.ElapsedMilliseconds); }
public void TestStopIdle() { BlockingThreadPool threadPool = new BlockingThreadPool(2, 2); Thread.Sleep(50); Assert.That(threadPool.Stop(50), Is.True); //check that Stop does not fail on a stopped pool Assert.That(threadPool.Stop(50), Is.True); }
public void TestStopBusy() { MessageLog log = new MessageLog(); for (int i = 0; i < TestIterationsCount; i++) { BlockingThreadPool threadPool = new BlockingThreadPool(3, 3); log.Clear(); threadPool.Execute(() => { log.Log("task 1: started"); // T = 0 try { // finally block is required to ignore Thread.Interrupt and Thread.Abort } finally { Thread.Sleep(200); } log.Log("task 1: finished"); // T = 200 }, 100); Thread.Sleep(50); // T = 50 threadPool.Execute(() => { log.Log("task 2: started"); // T = 50 try { // finally block is required to ignore Thread.Interrupt and Thread.Abort } finally { Thread.Sleep(250); } log.Log("task 2: finished"); // T = 300 }, 100); Thread.Sleep(50); // T = 50 threadPool.Execute(() => { log.Log("task 3: started"); // T = 100 log.Log($"task 4 queued: {threadPool.Execute(() => { }, 300)}"); // T = 150 log.Log("task 3: finished"); // T = 150 }, 100); Thread.Sleep(50); // T = 150 Stopwatch sw = Stopwatch.StartNew(); Assert.That(threadPool.Stop(100), Is.False); // T = 250 Assert.That(sw.ElapsedMilliseconds, Is.GreaterThan(75).And.LessThan(125)); sw.Restart(); Assert.That(threadPool.Execute(() => { }, 100), Is.False); Assert.That(sw.ElapsedMilliseconds, Is.LessThan(25)); sw.Restart(); Assert.That(threadPool.Stop(100), Is.True); // T = 300 Assert.That(sw.ElapsedMilliseconds, Is.GreaterThan(25).And.LessThan(75)); //check that Stop does not fail on a stopped pool sw.Restart(); Assert.That(threadPool.Stop(100), Is.True); // T = 300 Assert.That(sw.ElapsedMilliseconds, Is.LessThan(25)); Assert.That(log.GetLog(), Is.EqualTo(new string[] { "task 1: started", "task 2: started", "task 3: started", "task 4 queued: False", "task 3: finished", "task 1: finished", "task 2: finished" })); } }
public void TestPerformance() { const int poolThreadCount = 100; const int taskDelay = 10; BlockingThreadPool threadPool = new BlockingThreadPool(poolThreadCount, poolThreadCount*2); object lockObject = new object(); long executedTasks = 0; long rejectedTasks = 0; long loopIterations = 0; int threadCount = 0; int maxThreadCount = 0; Action task = () => { var newThreadCount = Interlocked.Increment(ref threadCount); lock (lockObject) { if (newThreadCount > maxThreadCount) { maxThreadCount = newThreadCount; } } Thread.Sleep(taskDelay); Interlocked.Increment(ref executedTasks); Interlocked.Decrement(ref threadCount); }; Stopwatch sw = Stopwatch.StartNew(); while (sw.ElapsedMilliseconds < 1000) { loopIterations++; for (int i = 0; i < 100; i++) { if (!threadPool.Execute(task, taskDelay + 100)) { rejectedTasks++; } } } Assert.That(threadPool.Stop(1000), Is.True); Console.WriteLine("executedTasks:\t{0}", executedTasks); Console.WriteLine("rejectedTasks:\t{0}", rejectedTasks); Console.WriteLine("maxThreadCount:\t{0}", maxThreadCount); Console.WriteLine("loopIterations:\t{0}", loopIterations); Assert.That(maxThreadCount, Is.EqualTo(poolThreadCount)); Assert.That(rejectedTasks, Is.EqualTo(0)); }