/// <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;

            tasksDetails = new ParallelRunningSubTaskDetails[numberOfTasks];
            result.BuildProgressInformation.SignalStartRunTask(GetStatusInformation(null));
            logger.Info("Starting parallel task with {0} sub-task(s)", numberOfTasks);

            // Initialise the arrays
            var events  = new ManualResetEvent[numberOfTasks];
            var results = new IIntegrationResult[numberOfTasks];

            for (var loop = 0; loop < numberOfTasks; loop++)
            {
                events[loop]       = new ManualResetEvent(false);
                results[loop]      = result.Clone();
                tasksDetails[loop] = new ParallelRunningSubTaskDetails(loop, result);
            }

            // Launch each task using the ThreadPool
            var countLock    = new object();
            var successCount = 0;
            var failureCount = 0;

            for (var loop = 0; loop < numberOfTasks; loop++)
            {
                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];
                        RunTask(task, taskResult, tasksDetails[taskNumber]);
                    }
                    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++;
                        }
                    }

                    tasksDetails[taskNumber].Finished = true;
                    tasksDetails[taskNumber].ParentResult.BuildProgressInformation.UpdateStartupInformation(GetStatusInformation(tasksDetails[taskNumber]));

                    // Tell everyone the task is done
                    events[taskNumber].Set();
                }, 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);
        }
Exemplo n.º 2
0
        /// <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;
            tasksDetails = new ParallelRunningSubTaskDetails[numberOfTasks];
            result.BuildProgressInformation.SignalStartRunTask(GetStatusInformation(null));
            logger.Info("Starting parallel task with {0} sub-task(s)", numberOfTasks);

            // Initialise the arrays
            var events = new ManualResetEvent[numberOfTasks];
            var results = new IIntegrationResult[numberOfTasks];

            for (var loop = 0; loop < numberOfTasks; loop++)
            {
                events[loop] = new ManualResetEvent(false);
                results[loop] = result.Clone();
                tasksDetails[loop] = new ParallelRunningSubTaskDetails(loop, result);
            }

            // Launch each task using the ThreadPool
            var countLock = new object();
            var successCount = 0;
            var failureCount = 0;
            for (var loop = 0; loop < numberOfTasks; loop++)
            {
                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];
                        RunTask(task, taskResult, tasksDetails[taskNumber]);
                    }
                    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++;
                        }
                    }

                    tasksDetails[taskNumber].Finished = true;
                    tasksDetails[taskNumber].ParentResult.BuildProgressInformation.UpdateStartupInformation(GetStatusInformation(tasksDetails[taskNumber]));

                    // Tell everyone the task is done
                    events[taskNumber].Set();

                }, 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;
        }