MSBuild:并行生成和.Net项目

MSBuild:并行生成和.Net项目,build,msbuild,parallel-processing,Build,Msbuild,Parallel Processing,我编写了一个MSBuild项目文件,试图并行构建VS2010解决方案的所有配置: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> <ItemGroup> <BuildFile Include="$(SourceRoot)MyProject.sln" /> <Config Include="Debug">

我编写了一个MSBuild项目文件,试图并行构建VS2010解决方案的所有配置:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <ItemGroup>
    <BuildFile Include="$(SourceRoot)MyProject.sln" />
    <Config Include="Debug">
      <Configuration>Debug</Configuration>
    </Config>
    <Config Include="Release">
      <Configuration>Release</Configuration>
    </Config>
  </ItemGroup>

  <Target Name="BuildAll" Outputs="%(Config.Configuration)">
    <Message Text="Start building for configuration: %(Config.Configuration)" />
    <MSBuild Projects="@(BuildFile)"
             Properties="Configuration=%(Config.Configuration)"
             Targets="Build" />
  </Target>  
</Project> 
问题是我的解决方案有许多.Net项目,它们都具有相同的输出文件夹。这些项目还使用相同的外部部件

因此,通常会同时生成两个输出可执行文件,并同时复制它们的依赖项。这会导致以下错误:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(3001,9): 
error MSB3021: 
Unable to copy file "xxx\NLog.dll" to "D:\src\Blackbird\shared\bin\debug\NLog.xml". The process 
cannot access the file 'xxx\NLog.dll because it is being used by another process. 
我认为这意味着:“两个不同的项目使用NLog,并试图同时将其程序集复制到输出文件夹中”

有没有办法绕过这个问题?我确实希望避免修改解决方案中的所有项目

查看任务源代码“C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(3001,9)”,我发现可以让msbuild重试复制:

<Copy
    SourceFiles="@(ReferenceCopyLocalPaths)"
    DestinationFiles="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')"
    SkipUnchangedFiles="$(SkipCopyUnchangedFiles)"
    OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
    Retries="$(CopyRetryCount)"
    RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
    UseHardlinksIfPossible="$(CreateHardLinksForCopyLocalIfPossible)"
    Condition="'$(UseCommonOutputDirectory)' != 'true'"
    > 

我已尝试设置变量CopyRetryCount、CopyreTryDelayMillicles。。。我希望,如果复制失败,几毫秒后完成的另一个复制会成功。但我无法设置这些参数。我怎样才能改变它们


还有别的解决办法吗?

我找到了解决办法

<MSBuild Projects="@(BuildFile)"
  Properties="Configuration=%(Config.Configuration);Retries=10;RetryDelayMilliseconds=50"
  Targets="Build" />

在我的上一次测试中,它生成了36次此警告!是否有方法抑制警告MSB0326?

通常,在生成期间运行的任何操作都不能在其输入上获取独占锁-仅共享读取锁。生成过程中的某些内容(可能是NLog,不管是什么)似乎违反了这一点-它对输入
“xxx\NLog.dll”
,进行独占锁定,因此当另一个msbuild节点尝试复制相同的输入时,它会失败


重试对于您的特定症状来说是一个合理的解决方法,尽管它不能保证总是成功。

我也有同样的问题。我需要为我的防病毒软件添加适当的异常,以避免扫描MsBuild生成的DLL。

您是将NLog作为产品的一部分构建,还是将其签入源代码管理?如果您正在构建它,您的一些项目是否可能引用二进制位置而不是项目?
<MSBuild Projects="@(BuildFile)"
  Properties="Configuration=%(Config.Configuration);Retries=10;RetryDelayMilliseconds=50"
  Targets="Build" />
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(3001,9): 
warning MSB3026: Could not copy 
"D:\src\xxx\System.Data.SQLite.pdb" to "..\Debug\System.Data.SQLite.pdb". 
Beginning retry 1 in 50ms. The process cannot access the file 
'..\Debug\System.Data.SQLite.pdb' because it is being used by another process.