/// <summary> /// Runs the task, given the specified <see cref="IIntegrationResult"/>, in the specified <see cref="IProject"/>. /// </summary> /// <param name="result"></param> protected override bool Execute(IIntegrationResult result) { // Initialise the task var logger = Logger ?? new DefaultLogger(); var numberOfTasks = Tasks.Length; _TasksStatuses = new _RunningSubTaskStatus[numberOfTasks]; result.BuildProgressInformation.SignalStartRunTask(_getStatusInformation(false)); logger.Info("Starting parallel task with {0} sub-task(s)", numberOfTasks); // Initialise the arrays var events = new ManualResetEvent[numberOfTasks]; var results = new IIntegrationResult[numberOfTasks]; // Launch each task using the ThreadPool var countLock = new object(); var successCount = 0; var failureCount = 0; for (var loop = 0; loop < numberOfTasks; loop++) { events[loop] = new ManualResetEvent(false); results[loop] = result.Clone(); _TasksStatuses[loop] = new _RunningSubTaskStatus(result); ThreadPool.QueueUserWorkItem((state) => { var taskNumber = (int)state; var taskName = string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0} [{1}]", Tasks[taskNumber].GetType().Name, taskNumber); try { Thread.CurrentThread.Name = string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0} [Parallel-{1}]", result.ProjectName, taskNumber); logger.Debug("Starting task '{0}'", taskName); // Start the actual task var task = Tasks[taskNumber]; var taskResult = results[taskNumber]; taskResult.BuildProgressInformation.OnStartupInformationUpdatedUserObject = _TasksStatuses[taskNumber]; taskResult.BuildProgressInformation.OnStartupInformationUpdated = SubTaskStartupInformationUpdated; RunTask(task, taskResult); } catch (Exception error) { // Handle any error details results[taskNumber].ExceptionResult = error; results[taskNumber].Status = IntegrationStatus.Failure; logger.Warning("Task '{0}' failed!", taskName); } // Record the results lock (countLock) { if (results[taskNumber].Status == IntegrationStatus.Success) { successCount++; } else { failureCount++; } } // Tell everyone the task is done events[taskNumber].Set(); _TasksStatuses[taskNumber].Finished = true; _TasksStatuses[taskNumber].ParentResult.BuildProgressInformation.UpdateStartupInformation(_getStatusInformation(true)); }, loop); } // Wait for all the tasks to complete logger.Debug("Waiting for tasks to complete"); WaitHandle.WaitAll(events); // Merge all the results logger.Info("Merging task results"); foreach (var taskResult in results) { result.Merge(taskResult); } // Clean up this.CancelTasks(); logger.Info("Parallel task completed: {0} successful, {1} failed", successCount, failureCount); return(true); }
/// <summary> /// Runs the task, given the specified <see cref="IIntegrationResult"/>, in the specified <see cref="IProject"/>. /// </summary> /// <param name="result"></param> protected override bool Execute(IIntegrationResult result) { // Initialise the task var logger = Logger ?? new DefaultLogger(); var numberOfTasks = Tasks.Length; _TasksStatuses = new _RunningSubTaskStatus[numberOfTasks]; result.BuildProgressInformation.SignalStartRunTask(_getStatusInformation(false)); logger.Info("Starting parallel task with {0} sub-task(s)", numberOfTasks); // Initialise the arrays var events = new ManualResetEvent[numberOfTasks]; var results = new IIntegrationResult[numberOfTasks]; // Launch each task using the ThreadPool var countLock = new object(); var successCount = 0; var failureCount = 0; for (var loop = 0; loop < numberOfTasks; loop++) { events[loop] = new ManualResetEvent(false); results[loop] = result.Clone(); _TasksStatuses[loop] = new _RunningSubTaskStatus(result); ThreadPool.QueueUserWorkItem((state) => { var taskNumber = (int)state; var taskName = string.Format(System.Globalization.CultureInfo.CurrentCulture,"{0} [{1}]", Tasks[taskNumber].GetType().Name, taskNumber); try { Thread.CurrentThread.Name = string.Format(System.Globalization.CultureInfo.CurrentCulture,"{0} [Parallel-{1}]", result.ProjectName, taskNumber); logger.Debug("Starting task '{0}'", taskName); // Start the actual task var task = Tasks[taskNumber]; var taskResult = results[taskNumber]; taskResult.BuildProgressInformation.OnStartupInformationUpdatedUserObject = _TasksStatuses[taskNumber]; taskResult.BuildProgressInformation.OnStartupInformationUpdated = SubTaskStartupInformationUpdated; RunTask(task, taskResult); } catch (Exception error) { // Handle any error details results[taskNumber].ExceptionResult = error; results[taskNumber].Status = IntegrationStatus.Failure; logger.Warning("Task '{0}' failed!", taskName); } // Record the results lock (countLock) { if (results[taskNumber].Status == IntegrationStatus.Success) { successCount++; } else { failureCount++; } } // Tell everyone the task is done events[taskNumber].Set(); _TasksStatuses[taskNumber].Finished = true; _TasksStatuses[taskNumber].ParentResult.BuildProgressInformation.UpdateStartupInformation(_getStatusInformation(true)); }, loop); } // Wait for all the tasks to complete logger.Debug("Waiting for tasks to complete"); WaitHandle.WaitAll(events); // Merge all the results logger.Info("Merging task results"); foreach (var taskResult in results) { result.Merge(taskResult); } // Clean up this.CancelTasks(); logger.Info("Parallel task completed: {0} successful, {1} failed", successCount, failureCount); return true; }