MSBuild: обработка встроенных задач

Я работаю с MSBuild (версия Framework v4.0.30319 - 32-разрядная) в Windows 2008 x64. Хотел понять, как MSBuild управляет встроенными задачами. Будет ли он компилироваться один раз за вызов задачи? Или он будет компилироваться один раз и повторно использоваться для каждого вызова задачи?

Я запустил MSBuild с аргументом «/m» и попытался внести преднамеренную ошибку в код 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>

person Parag Doke    schedule 10.08.2013    source источник
comment
Не обязательно связано с вашим вопросом, но в опубликованном вами примере не будет выполняться параллельная сборка. В вашем случае вызов задачи ‹MSBuild› будет выполняться последовательно, в цикле, поэтому значение атрибута BuildInParallel не будет действовать. Если вы хотите действительно параллельную сборку, вам придется создать несколько файлов проекта и передать их в атрибуте Projects задаче MSBuild.   -  person seva titov    schedule 12.08.2013
comment
@SevaTitov Спасибо за этот вклад. Я не знал об этом.   -  person Parag Doke    schedule 13.08.2013
comment
@SevaTitov Сева снова привет. От старшего коллеги я научился параллельному выполнению целей из одного и того же файла MSBuild. См. этот вопрос для примера: задача через c Sharp">stackoverflow.com/questions/21459302/. Это включает передачу ItemGroup в атрибут Projects.   -  person Parag Doke    schedule 31.01.2014


Ответы (1)


Выполнение вашего примера под ProcMon на моем компьютере с MSBuild 4.5 показывает следующее:

  1. Временная сборка создается MSBuild один раз для каждой сборки в пользовательской папке %TEMP%. (На самом деле сборку создал csc.exe, но я думаю, что это просто побочный эффект того, как выполняется генерация кода).
  2. Исходный код находился во временном файле .cs, также в папке %TEMP%.
  3. К концу сборки все файлы (исходные файлы, а также выходные сборки) удаляются.

Другими словами, вы увидите производительность при первом вызове задачи во время сборки. Все последующие вызовы задачи будут использовать кэшированную сборку. После того, как сборка кэша потеряна, сборку необходимо создать заново, а это означает, что если вам нужна быстрая инкрементная сборка, вы можете воспользоваться предварительно скомпилированной DLL.

person seva titov    schedule 12.08.2013
comment
Спасибо Сева. Я должен был подумать о ProcMon. Но никогда не поздно :-). Приму этот намек для последующих тестов. - person Parag Doke; 13.08.2013