如何在MSBuild中并行运行任务

如何在MSBuild中并行运行任务,msbuild,parallel-processing,Msbuild,Parallel Processing,除非我严重误解了MSBuild,否则任务是按照“目标”节点中出现的文档顺序执行的 我希望能够指定两个任务(例如xcopy任务)可以并行运行。我原以为会有一个“并行”任务或其他什么…?我认为除了使用一些外部工具之外,没有其他方法可以做到这一点。我怀疑这是因为这引入了MS选择暂时忽略的潜在依赖性问题,允许外部工具供应商解决这个问题(并为此收取相当多的费用)。MSBuild有一个/m命令行开关,告诉它可以使用的最大并发进程数。默认值为1/m:x将使用x个进程/m将使用计算机上的处理器数量 我在Visu

除非我严重误解了MSBuild,否则任务是按照“目标”节点中出现的文档顺序执行的


我希望能够指定两个任务(例如xcopy任务)可以并行运行。我原以为会有一个“并行”任务或其他什么…?

我认为除了使用一些外部工具之外,没有其他方法可以做到这一点。我怀疑这是因为这引入了MS选择暂时忽略的潜在依赖性问题,允许外部工具供应商解决这个问题(并为此收取相当多的费用)。

MSBuild有一个
/m
命令行开关,告诉它可以使用的最大并发进程数。默认值为1<代码>/m:x将使用x个进程
/m
将使用计算机上的处理器数量


我在VisualStudio中使用了这个快捷方式,通过并行编译项目来更快地运行构建。Scott Hanselman对此发表了几篇文章。

如前所述,您无法在任务级别甚至目标级别进行并行化。MSBuild只能并行生成项目(即MSBuild项目文件)。因此,必须在指定的多个项目中使用,并且BuildInParallel属性应设置为true。还要确保在命令行上调用构建时,会发送/m开关


我的书:

在MSBuild扩展包中尝试新的并行任务-

下面是一个并行运行MSBuild目标的方法示例。想法是一样的。。。将此msbuild文件本身显示为要生成的项目。我从我自己的问题中复制了它:


TargetToInvoke=平行TARGET1
TargetToInvoke=平行TARGET2

谢谢,但我对在任务级别引入显式并行感兴趣;就我所见,这仅适用于非依赖的MSBuild项目。我可能会看看是否可以将任务转换为单独的项目。我认为visual studio(msbuild)已经并行编译了文件,甚至在一个项目内。@bayinhuang:我认为CL任务是能够并行编译多个文件,但MSBuild中没有允许您自己使用该功能的内容。投票:记住使用
/m
标志调用MSBuild.exe。。。我没有,并且对它没有并行生成感到失望…您的脚本似乎可以工作,但不知何故,我的值没有传递到您生成的msbuild exe。有没有办法传递所有这些价值观?
<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>