Quantcast
Channel: Mike Fourie » MSBuild Extension Pack
Viewing all articles
Browse latest Browse all 21

Executing MSBuild Targets in Parallel – Part 2

$
0
0

[ In this series – Part 1, Part 2 ]

Part 1 provided an introduction to using the new parallel task in the MSBuild Extension Pack. Here is the file I ended Part 1 with, having knocked a great deal of execution time off the build.

<Project ToolsVersion="4.0" DefaultTargets="Default" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$<MSBuildExtensionsPath>\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks"/>
  <ItemGroup>
    <MyTargetSets Include="1">
      <Targets>Target2</Targets>
    </MyTargetSets>
    <MyTargetSets Include="2">
      <Targets>Target1;Target3</Targets>
    </MyTargetSets>
  </ItemGroup>
  <Target Name="Default">
    <MSBuild.ExtensionPack.Framework.Parallel TaskAction="BuildTargetSetsInParallel" Targets="@<MyTargetSets>"/>
  </Target>
  <Target Name="Target1">
    <MSBuild.ExtensionPack.Framework.Thread TaskAction="Sleep" Timeout="1000"/>
  </Target>
  <Target Name="Target2">
    <MSBuild.ExtensionPack.Framework.Thread TaskAction="Sleep" Timeout="4000"/>
  </Target>
  <Target Name="Target3">
    <MSBuild.ExtensionPack.Framework.Thread TaskAction="Sleep" Timeout="2000"/>
  </Target>
</Project>

In this part I’ll cover maintaining state, limitations and some general tips.

State

Let’s start with state. By state I mean the Properties and ItemGroups that have been set during execution, the static ones should be fine assuming we don’t alter any conditional logic evaluations.

Limitation 1 – there is no support for passing ItemGroups within and between parallel executions

Limitation 2 – there is no support for passing Properties within and between parallel executions. You may of course use environment variables, files, registry etc. but no vanilla support.

What is supported is the passing of calling properties to the parallel target sets. Take this sample, executed using msbuild parallel2.proj /p:MyProperty=Mike

<Project ToolsVersion="4.0" DefaultTargets="Default" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Import Project="$(MSBuildExtensionsPath)\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks"/>
    <ItemDefinitionGroup>
        <MyTargetSets1>
            <Properties>MyProperty=$(MyProperty)</Properties>
        </MyTargetSets1>
        <MyTargetSets2>
            <Properties>MyProperty=$(MyProperty)</Properties>
        </MyTargetSets2>
    </ItemDefinitionGroup>
    <ItemGroup>
        <MyTargetSets1 Include="1">
            <Targets>Target2</Targets>
        </MyTargetSets1>
        <MyTargetSets1 Include="2">
            <Targets>Target1;Target3</Targets>
        </MyTargetSets1>
        <MyTargetSets2 Include="1">
            <Targets>Target4</Targets>
        </MyTargetSets2>
        <MyTargetSets2 Include="2">
            <Targets>Target5</Targets>
        </MyTargetSets2>
    </ItemGroup>
    <Target Name="Default" DependsOnTargets="BuildSet1;BuildSet2"/>
    <Target Name="BuildSet1">
        <MSBuild.ExtensionPack.Framework.Parallel TaskAction="BuildTargetSetsInParallel" Targets="@(MyTargetSets1)"/>
    </Target>
    <Target Name="BuildSet2">
        <MSBuild.ExtensionPack.Framework.Parallel TaskAction="BuildTargetSetsInParallel" Targets="@(MyTargetSets2)"/>
    </Target>
    <Target Name="Target1">
        <MSBuild.ExtensionPack.Framework.Thread TaskAction="Sleep" Timeout="1000"/>
    </Target>
    <Target Name="Target2">
        <MSBuild.ExtensionPack.Framework.Thread TaskAction="Sleep" Timeout="4000"/>
        <Message Text="Target2 Value - $(MyProperty)" Importance="high"/>
    </Target>
    <Target Name="Target3">
        <MSBuild.ExtensionPack.Framework.Thread TaskAction="Sleep" Timeout="2000"/>
    </Target>
    <Target Name="Target4">
        <MSBuild.ExtensionPack.Framework.Thread TaskAction="Sleep" Timeout="4000"/>
        <Message Text="Target4 Value - $(MyProperty)" Importance="high"/>
    </Target>
    <Target Name="Target5">
        <MSBuild.ExtensionPack.Framework.Thread TaskAction="Sleep" Timeout="4000"/>
    </Target>
</Project>

We get

image

The key part here is the ItemGroupDefinition data set during the initial call. This saves any configured properties for use during execution.

Thumbs up Tip: If you have an InitialTarget set, this will be executed for every Target execution. You should either remove the InitialTarget configuration and call it manually, or condition it’s execution and then use the AdditionalProperties property so skip it’s execution on all but a pre-determined target.

Limitation 3 – there is no support for cancellation within a parallel execution. If a target fails though, any subsequent parallel target sets are not executed.

The cancellation limitation is something I plan to address shortly for the next release of the MSBuild Extension Pack.

Thumbs up Tip: If you only need a single target within a set to complete, set WaitAll=”false”. Note though that the other targets will still execute, but execution of the rest of your project will continue.

Thanks for taking time to read this and let me know how you get along with the task..

Mike


Filed under: MSBuild Extension Pack Tagged: MSBuild, Parallel

Viewing all articles
Browse latest Browse all 21

Trending Articles