public void TemplateService_CanParseTemplatesInParallel_WithThreadPool() { var service = new TemplateService(); const int count = 10; const string template = "<h1>Hello you are @Model.Age</h1>"; /* As we are leaving the threading to the pool, we need a way of coordinating the execution * of the test after the threadpool has done its work. ManualResetEvent instances are the way. */ var resetEvents = new ManualResetEvent[count]; for (int i = 0; i < count; i++) { // Capture enumerating index here to avoid closure issues. int index = i; string expected = "<h1>Hello you are " + index + "</h1>"; resetEvents[index] = new ManualResetEvent(false); var model = new Person { Age = index }; var item = new ThreadPoolItem<Person>(model, resetEvents[index], m => { string result = service.Parse(template, model); Assert.That(result == expected, "Result does not match expected: " + result); }); ThreadPool.QueueUserWorkItem(item.ThreadPoolCallback); } // Block until all events have been set. WaitHandle.WaitAll(resetEvents); service.Dispose(); }