Repository metrics
- Stars
- (5,062 stars)
- PR merge metrics
- (Avg merge 11d 7h) (125 merged PRs in 30d)
Description
Right now in our repo we have a series of relatively slow tasks that we run <Exec> on one by one. (This is the crossgen phase of the .NET libraries build). To make these run faster, we would like to run them in parallel.
Right now to do that with MSBuild our only option is to use the <MSBuild> task, which would require passing all the necessary properties over, make a lot more noise in the log (new project and target events) and be harder to read and maintain. When you start passing global properties to MSBuild tasks the build gets more difficult to reason about.
What would be ideal would be to be able to write
<Exec Commands="@(CrossgenCommands)" ... usual parameters, same for all commands ...
ExecuteInParallel="true"
/>
Exec (and ToolTask) are complicated - all those pipes and events - it is daunting to consider making all that understand parallelism. Fortunately it seems to me it is likely possible to do this with the "adapter" pattern in a rather straightforward way without modifying that code, as follows:
- If ExecuteInParallel is true, instead of continuing execution as normal, Exec would begin a
Parallel.Forstyle loop. Each loop: - Instantiates an Exec task with the same IBuildEngineX passed in. (It seems that IBuildEngineX and TaskLoggingHelper are thread safe.)
- Set ExecuteInParallel to false on the new task object. Set Command to the n'th command. Pass through all other parameters verbatim.
- Call Execute() on the task.
- Continue the loop.
This should cause all the commands to get executed with the right parameters, in some reasonable level of parallelism, with log messages interleaved.
Notes:
- If it was desired to make clear in some way which messages come from which instantiation, that could be achieved by passing in a custom IBuildEngineX which contains a type derived from TaskLoggingHelper that wraps the real TaskLoggingHelper. But personally, I'd just be glad for the thing to run in parallel. And interleaved console output is what most of us look at every day, not strongly typed MSBuild logs.
- As an alternative approach, MSBuild could add a virtual
ExecuteInParallelproperty on any task, and handle everything itself including scheduling - as dummy projects. But the above is simpler and could be replaced with this approach later.