我可以使用元数据缓存ItemGroup吗?

时间:2014-12-07 14:25:46

标签: msbuild

假设我有一个包含元数据的ItemGroup需要一些时间来构建(10秒):

<Target Name="BuildItemGroup">
    <ItemGroup>
        <File Include="5">
            <Value>5a</Value>
        </File>
        <File Include="4">
            <Value>4a</Value>
        </File>
        ...
    </ItemGroup>
    <Message Text="Wait 10 seconds..." Importance="High" />
</Target>

我将在递归的MSBuild任务中几次使用相同的ItemGroup:

<Target Name="Recursive" DependsOnTargets="BuildItemGroup" Condition="$(Value) > 0" >
    <PropertyGroup>
        <Value>$([MSBuild]::Subtract($(Value), 1))</Value>
    </PropertyGroup>

    <MSBuild Projects="$(MSBuildProjectFile)" Targets="Recursive" Properties="Value=$(Value)" />
</Target>

<PropertyGroup>
   <Value>5</Value>
</PropertyGroup>

<Target Name="Default" DependsOnTargets="Recursive" />

4个循环完成Recursive任务需要额外40秒。有没有办法以这种方式缓存ItemGroup以进行循环使用?

1 个答案:

答案 0 :(得分:1)

不,调用MSBuild任务将创建新的上下文,该上下文将重新评估所有属性和项目。 在parent \ child上下文之间传递数据的唯一方法是属性(以及成为全局属性的环境变量)。

根据此列表的大小 - 您可以尝试将其作为属性传递(丢失元数据)并在子msbuild上下文中重新创建itemgroup。

或者您可以使用C#切换到内联任务,并使用完整的C#功能切换到任何您想要的内容 - 例如将数据保存到磁盘并从文件中读回。

更新:最后我做了这样的内联任务。实际上,这是一个要保存的任务和另一个 - 从磁盘加载持久化的项目。有点难看的代码 - 我必须为Item和元数据类创建一个可序列化的副本。但它作为一个PoC已经足够好了。它无法保证在多线程环境中安全运行,尤其是在200多个项目的情况下。 See the code in this repository