public void Ensure_CancelToken_StopsLongRunningThread() { //Arrange using (var tokenSrc = new CancellationTokenSource()) { using (var pool = new CustomThreadPool3(tokenSrc.Token)) { //Act var queued = pool.QueueUserWorkItem((c, o) => { Thread.Sleep(TimeSpan.FromSeconds(60)); //60 seconds }, null); Assert.IsTrue(queued); Thread.Sleep(TimeSpan.FromMilliseconds(100)); //send cancel request to the pool tokenSrc.Cancel(); Assert.AreEqual(1, pool.TotalThreads); //still 1 thread running. //wait for 5 seconds now and see if thread have exicted Thread.Sleep(TimeSpan.FromSeconds(1)); Assert.AreEqual(1, pool.TotalThreads); //since the task is very long running, pool will let it finish before exiting all threads } } }
public void Ensure_CancelToken_StopsThreadPool() { bool itemprocessed = false; //Arrange var settings = new ThreadPoolSettings() { MaxThreads = 2, MinThreads = 1, ThreadIdleTimeout = new TimeSpan(0, 0, 0, 0, 10), //10 ms thread idle timeout }; using (var tokenSrc = new CancellationTokenSource()) { using (var pool = new CustomThreadPool3(settings, tokenSrc.Token)) { var queued = pool.QueueUserWorkItem((c, o) => { itemprocessed = true; //indicates the item is processed by the pool. }, null); Assert.IsTrue(queued); Assert.AreEqual(1, pool.TotalThreads); //Act //send cancel request to the pool tokenSrc.Cancel(); //try to enqueue another item queued = pool.QueueUserWorkItem((c, o) => { itemprocessed = true; //indicates the item is processed by the pool. }, null); //Assert Assert.IsFalse(queued); //after cancel, user cant queue new work } } }
public void Ensure_NewPool_HasUniqueName() { string name1, name2; using (var pool = new CustomThreadPool3(CancellationToken.None)) { Assert.IsNotNull(pool.Name); name1 = pool.Name; } using (var pool = new CustomThreadPool3(CancellationToken.None)) { Assert.IsNotNull(pool.Name); name2 = pool.Name; } Assert.AreNotEqual(name1, name2); }
public void QueueUserWorkItem_Return_False_When_CancelRequestedOnPool() { //Arrange using (var tokenSrc = new CancellationTokenSource()) { using (var pool = new CustomThreadPool3(tokenSrc.Token)) { //Act tokenSrc.Cancel(); //sends cancel signal to the pool var queued = pool.QueueUserWorkItem((c, o) => { //just empty work item, nothing to do.. }, null); //Assert Assert.IsFalse(queued); } } }
public void Pool_Raises_UserWorkItemException_Event_When_UserWorkItemThrowsUnhandledException() { bool eventCalled = false; //Arrange using (var tokenSrc = new CancellationTokenSource()) { using (var pool = new CustomThreadPool3(tokenSrc.Token)) { pool.UserWorkItemException += (object sender, WorkItemEventArgs e) => { Assert.AreEqual(123, (int)e.UserData); Assert.IsNotNull(e.Exception); eventCalled = true; }; //Act var queued = pool.QueueUserWorkItem((c, o) => { //throw unhandled exception from user's delegate throw new ApplicationException("test user exception"); }, 123); //Assert Assert.IsTrue(queued); Thread.Sleep(200); //ensures work item is processed. Assert.IsTrue(eventCalled); } } }
public void Ensure_ThreadPool_Shrinks_To_MinimumThreads() { //Arrange var settings = new ThreadPoolSettings() { MaxThreads = 4, MinThreads = 1, ThreadIdleTimeout = new TimeSpan(0, 0, 0, 0, 5), //5 ms thread idle timeout NewThreadWaitTime = TimeSpan.FromMilliseconds(0), }; //Act using (var pool = new CustomThreadPool3(settings, CancellationToken.None)) { //Act for (int i = 0; i < 100000; i++) { pool.QueueUserWorkItem((c, o) => { //Thread.Sleep(0); }, null); } //Assert Assert.AreEqual(4, pool.TotalThreads); //ensure reached to max limit //wait till all threads are drained while (pool.TotalThreads > settings.MinThreads) { //Console.WriteLine(pool.TotalThreads); Thread.Sleep(10); } //ensure pool reached to min size now Assert.AreEqual(1, pool.TotalThreads); } }
public void Ensure_ThreadPool_Runs_MinimumThreads() { //Arrange var settings = new ThreadPoolSettings() { MaxThreads = 100, MinThreads = 10, ThreadIdleTimeout = TimeSpan.FromMilliseconds(1), //1sec thread idle timeout }; //Act using (var pool = new CustomThreadPool3(settings, CancellationToken.None)) { //Assert Assert.AreEqual(10, pool.TotalThreads); //wait for 100ms and ensure pool still runs 10 threads Thread.Sleep(15); //Assert Assert.AreEqual(10, pool.TotalThreads); } }
public void Ensure_ThreadPool_Runs_MaximumThreads() { //Arrange var settings = new ThreadPoolSettings() { MaxThreads = 3, MinThreads = 1, ThreadIdleTimeout = new TimeSpan(0, 0, 0, 0, 5000), //5 sec. thread idle timeout NewThreadWaitTime = TimeSpan.FromMilliseconds(0), }; //Act using (var pool = new CustomThreadPool3(settings, CancellationToken.None)) { //Act for (int i = 0; i < 10000; i++) { pool.QueueUserWorkItem((c, o) => { Thread.Sleep(100); }, null); } //Assert Assert.AreEqual(3, pool.TotalThreads); } }
public void Ensure_QueueUserWorkItem_Enqueues_WorkItems() { //Arrange using (var tokenSrc = new CancellationTokenSource()) { using (var pool = new CustomThreadPool3(tokenSrc.Token)) { //Act for (int i = 0; i < 10; i++) { var queued = pool.QueueUserWorkItem((c, o) => { //just empty work item, nothing to do.. }, null); //Assert Assert.IsTrue(queued); } } } }