4

I'm working with MSBuild (Framework version v4.0.30319 - 32 bit one) on Windows 2008 x64. Wanted to understand how MSBuild manages inline tasks. Will it compile once per call to the task ? Or will it compile once and re-use for each call to the task ?

I ran MSBuild with the "/m" argument and tried introducing a deliberate error into the C# code. And MSBuild pointed me to 1 text file (under a temp folder somewhere in my profile folder). No other text file was generated. However, I didn't know how to figure this if there were no errors.

My intent behind trying to figure this out: To know if this will be efficient to the same order as using a compiled dll (instead of an inline task). The miniscule overhead of compiling inline task code is acceptable if the compile happens just once (because I will save on SCM aspects of the code and the binaries).

<?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>
Parag Doke
  • 863
  • 7
  • 17
  • Not necessaraly related to your question, but the example you posted will not exercise parallel build. In your case call to task will be executed sequentially, in a loop, so the value of "BuildInParallel" attribute will not take effect. If you want really parallel build, you will have to create multiple project files and pass them in "Projects" attribute to MSBuild task. – seva titov Aug 12 '13 at 02:01
  • @SevaTitov Thank you for this input. I wasn't aware about it. – Parag Doke Aug 13 '13 at 04:46
  • @SevaTitov Hi again Seva. From a senior colleague, I learnt a trick to execute targets from the same MSBuild file in parallel. See this question for a sample: http://stackoverflow.com/questions/21459302/evaluate-item-defined-in-msbuild-task-via-c-sharp. It does involve passing an ItemGroup to the Projects attribute. – Parag Doke Jan 31 '14 at 17:04

1 Answers1

3

Running your example under ProcMon on my machine with MSBuild 4.5 reveals the following:

  1. Temporary assembly is generated by MSBuild once per the build under user %TEMP% folder. (It was actually csc.exe that created the assembly, but I think this is just a side effect on how code generation is done).
  2. The source code was in temporary .cs file, also under %TEMP%.
  3. By the end of the build all files (source files as well as output assemblies) are deleted.

In other words, you will see a perf hit on first call to the task during the build. All subsequent calls to the task will use cached assembly. After the build the cache is lost, the assembly has to be re-created again, which means that if you are after fast incremental build, you might benefit from pre-compiled DLL.

seva titov
  • 11,720
  • 2
  • 35
  • 54
  • Thank you Seva. I should have thought of ProcMon. But never too late :-). Will take that hint for subsequent tests. – Parag Doke Aug 13 '13 at 04:47