Skip to content

Instantly share code, notes, and snippets.

@balarvs2002
Forked from wernight/gist:4978408
Created January 6, 2017 05:21
Show Gist options
  • Save balarvs2002/ace13ddfcb699c1fd10d393d2bcc64d1 to your computer and use it in GitHub Desktop.
Save balarvs2002/ace13ddfcb699c1fd10d393d2bcc64d1 to your computer and use it in GitHub Desktop.
Custom NAnt task to execute multiple <exec> tasks in parallel and wait until they all completed.
using System;
using System.Threading.Tasks;
using NAnt.Core;
using NAnt.Core.Attributes;
using NAnt.Core.Tasks;
namespace MyTasks
{
[TaskName("parallelexec")]
public class ParallelExecTask : TaskContainer
{
[BuildElementArray("exec", Required = true, ElementType = typeof(ExecTask))]
public ExecTask[] ExecTasks { get; set; }
[TaskAttribute("threadcount")]
public int ThreadCount { get; set; }
protected override void ExecuteTask()
{
var parallelOptions = new ParallelOptions();
if (ThreadCount > 0)
{
parallelOptions.MaxDegreeOfParallelism = ThreadCount;
Log(Level.Verbose, string.Format("Executing in parallel using at most {0} threads...", ThreadCount));
}
else
{
Log(Level.Verbose, string.Format("Executing in parallel using at most {0} threads...", ThreadCount));
}
try
{
Parallel.ForEach(ExecTasks, parallelOptions, Body);
}
catch (AggregateException e)
{
foreach (Exception innerException in e.InnerExceptions)
{
if (innerException is BuildException)
Log(Level.Error, innerException.Message);
else
throw innerException;
}
throw new BuildException("Parallel execution failed for " + e.InnerExceptions.Count + " of " + ExecTasks.Length + " commands executions (see the above log).", Location);
}
}
private void Body(ExecTask execTask)
{
try
{
execTask.Execute();
}
catch (BuildException e)
{
throw new BuildException("External Program Failed: " + execTask.ProgramFileName + " " + execTask.CommandLine + " (return code was " + execTask.ExitCode + ")", e);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment