为何MSBuild未并行执行目标?附测试项目示例
解决MSBuild跨项目调用同一文件时的串行执行问题
你遇到的核心问题是:两次MSBuild任务都指向同一个项目文件,MSBuild的节点调度机制会默认规避并行构建同一项目的风险(比如文件锁、状态冲突),所以自动将这两个请求串行化,哪怕你已经设置了BuildInParallel="true"和/m参数。
下面是几种可行的解决方案:
方案1:拆分目标到独立项目文件
把_T1和_T2分别放到两个单独的项目文件中(比如T1.proj和T2.proj),然后修改原项目的ItemGroup:
<ItemGroup> <_Project Include="T1.proj" Targets="_T1" /> <_Project Include="T2.proj" Targets="_T2" /> </ItemGroup>
这种方式下,MSBuild会识别为两个完全独立的项目,自然会并行执行构建请求。
方案2:添加唯一属性标识,让MSBuild视为不同项目实例
在每个_Project项中添加一个唯一的自定义属性,让MSBuild认为这是两个不同的构建任务:
<ItemGroup> <_Project Include="$(MSBuildThisFileFullPath)" Targets="_T1" Properties="UniqueId=1" /> <_Project Include="$(MSBuildThisFileFullPath)" Targets="_T2" Properties="UniqueId=2" /> </ItemGroup>
通过Properties参数传入不同的标识,MSBuild会将这两个请求当作独立的任务处理,从而触发并行执行。
方案3:直接并行执行当前项目的多个目标
不需要重复调用自身项目,直接在Build目标中指定要并行执行的多个目标,配合/m参数即可:
<Target Name="Build"> <MSBuild BuildInParallel="true" Projects="$(MSBuildThisFileFullPath)" Targets="_T1;_T2" /> </Target>
注意:这种方式要求_T1和_T2之间没有任何依赖关系(比如没有用DependsOnTargets关联),MSBuild会自动并行执行无依赖的目标。
修改完成后,重新执行msbuild /m /t:Build test.proj,就能看到两个ping命令并行执行了。
内容的提问来源于stack exchange,提问作者Alex I
相关产品推荐
相关产品推荐

