public void TestQueueUserWorkItem() { using (TestTask task = new TestTask()) { AffineThreadPool.QueueUserWorkItem(task.Callback); Assert.IsTrue(task.CallbackEvent.WaitOne(1000)); } }
public void TestQueueUserWorkItemWithState() { using (TestTask task = new TestTask()) { object state = new object(); AffineThreadPool.QueueUserWorkItem(task.Callback, state); Assert.IsTrue(task.CallbackEvent.WaitOne(1000)); Assert.AreSame(state, task.LastCallbackState); } }
public void TestExceptionFromUserWorkItem() { using (ManualResetEvent exceptionEvent = new ManualResetEvent(false)) { AffineThreadPool.ExceptionDelegate oldExceptionHandler = AffineThreadPool.ExceptionHandler; AffineThreadPool.ExceptionHandler = delegate(Exception exception) { exceptionEvent.Set(); }; try { AffineThreadPool.QueueUserWorkItem( delegate(object state) { throw new KeyNotFoundException(); } ); Assert.IsTrue(exceptionEvent.WaitOne(1000)); } finally { AffineThreadPool.ExceptionHandler = oldExceptionHandler; } } }
public void TestWaitingWorkItemsProperty() { int eventCount = AffineThreadPool.Processors; WaitTask[] tasks = new WaitTask[eventCount]; int createdTasks = 0; try { // CHECK: Is there danger that the thread pool still has not finished // queued items for other unit tests, thereby failing to meet // our expected task counts? // Create the tasks, counting up the created task counter. If an exception // occurs, we will roll back from there. for (createdTasks = 0; createdTasks < eventCount; ++createdTasks) { tasks[createdTasks] = new WaitTask(); } // Schedule the blocking tasks in the thread pool so it will not be able // to process the next task we add to the queue for (int index = 0; index < eventCount; ++index) { AffineThreadPool.QueueUserWorkItem(tasks[index].Callback); } // Wait for the tasks to start so they aren't preempted by the tasks we're // going to add (which would finish immediately). The affine thread pool // works on a first come first serve basis, but we don't want to rely on this // implementation detail in the unit test. for (int index = 0; index < eventCount; ++index) { Assert.IsTrue( tasks[index].StartEvent.WaitOne(10000), "Task " + index.ToString() + " was started" ); } // All Thread should now be active and no work items should be waiting Assert.AreEqual( createdTasks, AffineThreadPool.ActiveThreads, "ActiveThreads property equals number of tasks" ); Assert.AreEqual( 0, AffineThreadPool.WaitingWorkItems, "No waiting work items are in the queue" ); // Add a task to the queue and make sure the waiting work item count goes up AffineThreadPool.QueueUserWorkItem(delegate(object state) { }); Assert.AreEqual( 1, AffineThreadPool.WaitingWorkItems, "Added work item is waiting in the queue" ); // The same again. Now we should have 2 work items sitting in the queue AffineThreadPool.QueueUserWorkItem(delegate(object state) { }); Assert.AreEqual( 2, AffineThreadPool.WaitingWorkItems, "Both added work items are waiting in the queue" ); // Let the WaitTasks finish so we're not blocking the thread pool any longer for (int index = 0; index < eventCount; ++index) { tasks[index].WaitEvent.Set(); } // Wait for the tasks to end before we get rid of them for (int index = 0; index < eventCount; ++index) { Assert.IsTrue( tasks[index].FinishEvent.WaitOne(1000), "Task " + index.ToString() + " has finished" ); } } finally { for (--createdTasks; createdTasks >= 0; --createdTasks) { tasks[createdTasks].Dispose(); } } }