36

Unless I've grossly misunderstood MSBuild, tasks are executed in the document order in which they appear within a 'Target' node.

I'd like to be able to specify that two tasks (such as xcopy tasks) could run in parallel. I was expecting there to be a 'Parallel' task or something...?

Pete Montgomery
  • 4,060
  • 3
  • 30
  • 40
  • vote for it: https://visualstudio.uservoice.com/forums/121579-visual-studio-ide/suggestions/9604311-allow-custom-build-tools-to-run-in-parallel – Trass3r Dec 15 '16 at 12:11

6 Answers6

39

Try the new parallel task in the MSBuild Extension Pack - http://mikefourie.wordpress.com/2012/02/29/executing-msbuild-targets-in-parallel-part-1

Mike Fourie
  • 491
  • 1
  • 4
  • 3
21

As was stated, you cannot parallelise at the task level or even at the target level. MSBuild only will build projects (i.e. MSBuild project files) in parallel. So you have to use the MSBuild task with multiple projects specified and the BuildInParallel attribute should be set to true. Also make sure that when the build is invoked on the command line that the /m switch is sent it.

My Book: Inside the Microsoft Build Engine : Using MSBuild and Team Foundation Build

Prof. Falken
  • 24,226
  • 19
  • 100
  • 173
Sayed Ibrahim Hashimi
  • 43,864
  • 17
  • 144
  • 178
  • I think visual studio (msbuild) already compile files in parallel, even inside one project. – Baiyan Huang Sep 09 '13 at 13:13
  • 2
    @BaiyanHuang: I think that's the CL task being able to compile several files in parallel but there's nothing in MSBuild that allows you to use that functionality yourself. – Joey Feb 03 '14 at 11:34
11

MSBuild has a /m command line switch to tell it the maximum number of concurrent processes to build with. The default value is 1. /m:x will use x processes. /m will use the number of processors on computer.

I've used this as part of a shortcut in Visual Studio to run builds quicker by compiling projects in parallel. Scott Hanselman has a few posts about it here and here.

Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
adrianbanks
  • 81,306
  • 22
  • 176
  • 206
  • 2
    Thanks, but I'm interested in introducing explicit parallelism at the Task level; this works only for non-dependent MSBuild projects as far as I can see. I'll perhaps see if I can transform the tasks into separate projects. – Pete Montgomery Jun 16 '09 at 10:12
6

Here is an example of a way to run msbuild targets in parallel. The idea is same ... presenting this msbuild file itself as a project to build. I copied it from my own question: Evaluate item defined in msbuild task via C#

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0" DefaultTargets="Build">
<Target Name="Build" DependsOnTargets="PrepareEnvironmentForBuild;MapDrives">
    <Exec Command="$(MSBuildBinPath)\msbuild /nologo /clp:Verbosity=quiet $(MSBuildThisFileFullPath) /t:TargetWithConfidentialSteps"/>
    <ItemGroup>
        <StepsToRunInParallel Include="$(MSBuildThisFileFullPath)">
            <Properties>TargetToInvoke=ParallelTarget1</Properties>
        </StepsToRunInParallel>
        <StepsToRunInParallel Include="$(MSBuildThisFileFullPath)">
            <Properties>TargetToInvoke=ParallelTarget2</Properties>
        </StepsToRunInParallel>
    </ItemGroup>
    <MSBuild Projects="@(StepsToRunInParallel)" BuildInParallel="true" StopOnFirstFailure="true" Targets="InvokeInParallelWithinThisProject"/>

</Target>
<Target Name="InvokeInParallelWithinThisProject">
    <MSBuild Projects="$(MSBuildThisFileFullPath)" Targets="$(TargetToInvoke)" StopOnFirstFailure="true"/>
</Target>
<Target Name="ParallelTarget1">
    <Message Text="Hello from ParallelTarget1"/>
</Target>
<Target Name="ParallelTarget2">
    <Message Text="Hello from ParallelTarget2"/>
</Target>
<Target Name="PrepareEnvironmentForBuild">
    <Message Text="Hello from PrepareEnvironmentForBuild"/>
</Target>
<Target Name="MapDrives">
    <Message Text="Hello from MapDrives"/>
</Target>
<Target Name="TargetWithConfidentialSteps">
    <Message Text="Hush! Verbosity on the wrapper does not affect the Exec call." Importance="High"/>
</Target>

Community
  • 1
  • 1
Parag Doke
  • 863
  • 7
  • 17
  • 1
    Remember to call MSBuild.exe with the `/m`flag... I didn't and was disappointed that it didn't build in parallel... – Prof. Falken Mar 27 '19 at 16:01
  • Your script seems to work but somehow my values do not get passed on to the msbuild exe you spawn. Is there a way to pass on all these values? – ikku100 May 12 '20 at 19:06
  • 1
    Sorry @ikku100. Haven't used MSBuild for several years now :-( – Parag Doke Jan 18 '22 at 17:04
3

I don't think there is a way to do this other than using some external tool. I suspect this is because this introduces potential dependency problems that MS chooses to ignore for the time being, allowing external tool vendors to tackle the problem (and charge quite a bit of money for it).

Paul Sonier
  • 38,903
  • 3
  • 77
  • 117
0

For C++, you can do it with

  •  <MultiProcessorCompilation>true</MultiProcessorCompilation>
    

Which can be found if you search 'multi' under C++ > All Options of the Property pages of the project

More info here: https://devblogs.microsoft.com/cppblog/recommendations-to-speed-c-builds-in-visual-studio/

Jonathan
  • 6,741
  • 7
  • 52
  • 69