Параллельный запуск нескольких задач exec

#c# #.net #msbuild #msbuild-task #msbuild-target

#c# #.net #msbuild #msbuild-задача #msbuild-цель

Вопрос:

Я собираю несколько задач в процессе сборки. exec Каждое выполнение занимает около одной минуты, поэтому я хотел бы запускать их параллельно, чтобы повысить общую производительность сборки.

Цель, выполняющая несколько exec задач:

 <Target Name="CreatePackages" DependsOnTargets="Build" AfterTargets="Build">
  <Exec Command="SomeExecutable.exe %(SomeGroup.Location) </Exec>
</Target>
  

Определение ItemGroup :

 <ItemGroup>
  <SomeGroup Include="Production">
    <Location>SomePath/Production</Location>
  </SomeGroup>
  <SomeGroup Include="Test">
    <Location>SomePath/Test</Location>
  </SomeGroup>
  <SomeGroup Include="Development">
    <Location>SomePath/Development</Location>
  </SomeGroup>
</ItemGroup>
  

Как мне запускать эти exec задачи параллельно?

Ответ №1:

MSBuild выполняет распараллеливание не на уровне задачи или целевого уровня, а только на уровне проекта. Вы можете обернуть каждое отдельное местоположение в цель и вызвать сам проект параллельно (беспорядочно), или написать пользовательскую задачу с помощью TPL ( System.Threading.Tasks.Parallel ) и Microsoft.Build.Tasks.Exec или System.Diagnostics.Process (легко), или попробовать YieldDuringToolExecution (технически не распараллеливание, но другие задачи будут ждать меньше).

Комментарии:

1. Вы можете запускать цели параллельно. Если я как-то не очень смущен!

2. @davenewza Вроде как, посмотрите на скриншот, в нем есть 3 резюме сборки. Я думаю, будет точнее сказать, что он создавал проект трижды параллельно с одной целью для каждого, а не создавал проект с тремя параллельными целями, и это именно то, что я имел в виду под первым вариантом, хотя я бы рекомендовал вам выполнить второй вариант с TPL и пользовательской задачей.

3. @davenewza, технически MSBuild распараллеливается только на уровне проекта. Хитрость с пакетом расширений заключается в том, что он запускает несколько экземпляров MSBuild.exe параллельно, что эквивалентно вызову msbuild MyProject.proj /t:OneOfMyTargets . Это может выглядеть похоже на распараллеливание, поддерживаемое MSBuild, но это не так. Причина в том, что любые предварительные условия ваших целей будут выполняться несколько раз, что нарушает модель MSBuild. MSBuild (на уровне проекта) гарантирует, что любая цель будет выполнена не более одного раза. Я бы не рекомендовал использовать эту функциональность из пакета расширений.