如何在MSBuild中并行运行任务

时间:2022-10-26 21:35:05

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

除非我非常误解MSBuild,否则任务按文档顺序执行,它们出现在“Target”节点中。

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...?

我希望能够指定两个任务(例如xcopy任务)可以并行运行。我期待有一个'并行'任务或什么......?

5 个解决方案

#1


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.

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

Sayed Ibrahim Hashimi

Sayed Ibrahim Hashimi

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

我的书:Microsoft Build Engine内部:使用MSBuild和Team Foundation Build

#2


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

在MSBuild扩展包中尝试新的并行任务 - http://mikefourie.wordpress.com/2012/02/29/executing-msbuild-targets-in-parallel-part-1

#3


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.

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

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.

我已经将它用作Visual Studio中快捷方式的一部分,通过并行编译项目来更快地运行构建。 Scott Hanselman在这里和这里有一些关于它的帖子。

#4


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).

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

#5


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#

以下是并行运行msbuild目标的方法示例。这个想法是一样的......将这个msbuild文件本身呈现为一个要构建的项目。我从我自己的问题中复制了它:通过C#评估msbuild任务中定义的项目

<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>

#1


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.

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

Sayed Ibrahim Hashimi

Sayed Ibrahim Hashimi

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

我的书:Microsoft Build Engine内部:使用MSBuild和Team Foundation Build

#2


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

在MSBuild扩展包中尝试新的并行任务 - http://mikefourie.wordpress.com/2012/02/29/executing-msbuild-targets-in-parallel-part-1

#3


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.

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

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.

我已经将它用作Visual Studio中快捷方式的一部分,通过并行编译项目来更快地运行构建。 Scott Hanselman在这里和这里有一些关于它的帖子。

#4


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).

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

#5


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#

以下是并行运行msbuild目标的方法示例。这个想法是一样的......将这个msbuild文件本身呈现为一个要构建的项目。我从我自己的问题中复制了它:通过C#评估msbuild任务中定义的项目

<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>