MSBuild:处理内联任务

4
我正在使用Windows 2008 x64上的MSBuild(Framework版本为v4.0.30319-32位)。想了解MSBuild如何管理内联任务。它会在每次调用任务时编译一次吗?还是只编译一次并重复使用?我运行了带有“/m”参数的MSBuild,并尝试在C#代码中故意引入错误。然后MSBuild指向1个文本文件(位于我的个人资料文件夹中的某个临时文件夹下)。没有生成其他文本文件。但是,如果没有错误,我不知道该如何查找这个文件。
我尝试调查此问题的原因是: 要确定它是否与使用已编译的dll相同程度有效(而不是内联任务)。如果编译只发生一次,则可以接受内联任务代码编译的微小开销(因为我将节省代码和二进制SCM方面的开销)。
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="default" ToolsVersion="4.0">
  <Target Name="default">
    <ItemGroup>
      <A Include="1;2;3;4;5;6;7;8;9;10"/>
    </ItemGroup>
    <MSBuild Projects="$(MSBuildProjectFullPath)"
             BuildInParallel="true"
             Targets="Echoer"
             ToolsVersion="4.0"
             StopOnFirstFailure="true"
             Properties="Prop=%(A.Identity)"/>
  </Target>
  <Target Name="Echoer">
    <MyTask WhatToEcho="$(Prop)"/>
  </Target>
  <UsingTask TaskName="MyTask" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
    <ParameterGroup>
      <WhatToEcho ParameterType="System.String" Required="True"/>
    </ParameterGroup>
    <Task>
      <Code Language="cs" Type="Fragment">
        <![CDATA[
        Log.LogMessage("Property received: "+WhatToEcho);
        ]]>
      </Code>
    </Task>
  </UsingTask>
</Project>

不一定与您的问题相关,但您发布的示例将不会进行并行构建。在您的情况下,对<MSBuild>任务的调用将按顺序循环执行,因此“BuildInParallel”属性的值将不起作用。如果您想要真正的并行构建,则必须创建多个项目文件,并将它们传递到MSBuild任务的“Projects”属性中。 - seva titov
@SevaTitov 谢谢您的建议。我之前不知道这个。 - Parag Doke
@SevaTitov 你好,Seva!我从一个资深同事那里学到了一种技巧,可以在同一 MSBuild 文件中并行执行目标。可以参考这个问题的答案:http://stackoverflow.com/questions/21459302/evaluate-item-defined-in-msbuild-task-via-c-sharp。这确实涉及将 ItemGroup 传递给 Projects 属性。 - Parag Doke
1个回答

3
在我的机器上使用MSBuild 4.5运行您的示例,并在ProcMon下进行监视,结果如下:
  1. MSBuild为每个构建操作在用户%TEMP%文件夹下生成临时程序集。(实际上是由csc.exe创建程序集,但我认为这只是代码生成方式带来的副作用)。
  2. 源代码在临时.cs文件中,也位于%TEMP%下。
  3. 在构建结束后,所有文件(包括源文件和输出程序集)都将被删除。
换句话说,在构建过程中,对任务的第一次调用会带来性能损失。所有后续对该任务的调用都将使用缓存的程序集。在构建结束后,缓存将被清除,程序集必须重新创建。如果您想要快速的增量构建,则可以从预编译的DLL中受益。

谢谢Seva。我应该想到ProcMon的。但是现在也不晚:-)。会在后续测试中采纳这个提示。 - Parag Doke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接