public int Run() { var threads = new Thread[_noOfThreads]; var threadDatas = new ThreadRunner[_noOfThreads]; for (var i = 0; i < _noOfThreads; i++) { var threadRunner = new ThreadRunner(DefaultTestingThreadReportingPeriod, _loggerFactory.CreateLogger <ThreadRunner>()); threads[i] = new Thread(threadRunner.RunLoop); threadDatas[i] = threadRunner; threads[i].Start(); } var monitoringThread = new Thread(MonitoringThread); var monitoringThreadData = new MonitoringThreadData(threadDatas); monitoringThread.Start(monitoringThreadData); Thread.Sleep(_timeToRun); _logger.LogInformation("Exiting worker threads"); foreach (var threadData in threadDatas) { threadData.ShouldStop = true; } foreach (var thread in threads) { thread.Join(); } _logger.LogInformation("Exiting monitoring thread"); monitoringThreadData.WaitHandle.Set(); monitoringThread.Join(); var noOfRuns = threadDatas.Sum(x => x.Count); _logger.LogInformation(string.Format("Number of test runs = {0} on {1} threads, no of exceptions: {2}", noOfRuns, _noOfThreads, Exceptions.Count)); return(Exceptions.Count); }