.net 代码分析改进

.net 代码分析改进,.net,visual-studio,msbuild,code-analysis,static-code-analysis,.net,Visual Studio,Msbuild,Code Analysis,Static Code Analysis,静态CA使解决方案构建速度变慢。在我的情况下,速度比没有CA时慢2倍以上。我们可以禁用它,但这是一个错误的决定,失去它的力量。 那么我们能做什么呢 首先让我们看看CA是如何工作的。 您可以构建解决方案。在msbuild编译后的每个项目生成中,都会使用应分析的程序集路径调用目标fxcopcmd.exe。fxcopcmd。生成由VS使用的CA xml日志(或者可能是输出流)。fxcopcmd.exe加载程序集(fast)并同步分析它,因此只加载一个CPU,而3个(在我的例子中)什么也不做。只有在CA

静态CA使解决方案构建速度变慢。在我的情况下,速度比没有CA时慢2倍以上。我们可以禁用它,但这是一个错误的决定,失去它的力量。 那么我们能做什么呢

首先让我们看看CA是如何工作的。

您可以构建解决方案。在msbuild编译后的每个项目生成中,都会使用应分析的程序集路径调用目标fxcopcmd.exe。fxcopcmd。生成由VS使用的CA xml日志(或者可能是输出流)。fxcopcmd.exe加载程序集(fast)并同步分析它,因此只加载一个CPU,而3个(在我的例子中)什么也不做。只有在CA完成后,才能构建项目依赖链中的下一个项目

所以CA的弱点是我们可以改进它——强制它并行工作以使用所有CPU

我看到了这样的解决方案

要制作将从MSBUILD获取参数的假fxcopcmd.exe,请记住它,并立即向MSBUILD报告一切正常且没有错误(通过CA xml.log、成功文件或流..)。因此,MSBUILD将生成下一个项目,届时我们将使用保存的参数调用real fxcopcmd.exe。。。如果MSBUILD将在下一个项目中调用fxcopcmd.exe-我们将再次调用fxcopcmd.exe。。。因此,很少有进程会加载所有CPU。在真正的fxcopcmd.exe完成后,我们可以调用我们的MSBUILD目标,它将只调用microsoft.common.Targets中的CA目标,而不进行编译,我们的假fxcopcmd.exe将立即向MSBUILD-VS报告结果(CA在当时完成,我们有日志)

你觉得怎么样?这会加速吗? 为什么微软没有这样的员工,在CA中只使用一个CPU?

我曾经问过一个问题。在2012年的ALM峰会上,我讨论了这个话题,原因有很多(没有具体顺序)

  • 一旦ProjectRoslyn集成到VisualStudio产品中,代码分析引擎很可能会被替换。Roslyn将提供实时分析(如Resharper)和“修复”发现问题的能力
  • 该引擎非常CPU密集,并且已经使用了多个CPU,因此运行多个实例可能不会像您想象的那样对您有多大帮助。此外,fxcop可能非常I/O密集(加载程序集、pdb和其他文件),如果同时加载多个实例,情况只会变得更糟
  • 生成引擎需要访问生成输出。用于引用,但也用于其他任务。因此,它需要知道,当任务完成时,文件不再使用。例如,当您添加一个任务,将多个程序集合并在一起,然后删除旧的程序集时,它需要访问这些文件。简单的移动/打包/etc操作也是如此
  • 当发现代码分析问题(设置为level=error)时,尽早使构建失败的能力将不起作用,因为您只在最后收集结果。可能导致您构建所有内容,却发现您无法使用最终结果
正如您在中所看到的,Fxcop本身已经使用了多个线程,并且(至少在2010年附带的规则中)已经存在一些并发问题,导致我们在某些情况下关闭Fxcop的并发。如果希望fxcop使用更多(或更少)线程,可以编辑
fxcopcmd.exe.config
文件:

 <FxCopEngineSettings Version="1.32">
   <Engines>
     <Engine Name="Introspection" Enabled="True">
       <!-- Change this number to use more (or fewer) threads -->
       <Threading Count="1" />
       <EnableFlowAnalysis>True</EnableFlowAnalysis>
     </Engine>
   </Engines>
 </FxCopEngineSettings>

真的
虽然论坛帖子提到了VisualStudio2008,但我也将其应用于解决2010的问题

使FxCop更高效的一个最简单的方法是在编译完所有项目后调用它一次。这将导致它只加载一次所有符号和引用的程序集,并允许引擎最大限度地利用并行性。当您有一个混合了多个目标平台和cpu的解决方案时,或者当您想要为不同的项目使用不同的.rules文件时,这也存在一些问题


或者,您也可以执行与我相同的操作,即为本地解决方案配置FxCop,但不将其设置为在每个构建上运行。然后在Team Foundation Server Team Bug(或者您可能使用的任何其他构建服务器)中,重写FXCOP的配置,以“始终”运行。这样,在构建本地解决方案时不会对性能产生影响。它仍然允许您在本地(从“分析”菜单项)为整个解决方案运行代码分析,并且自动生成可以防止您签入有问题的代码。

为什么不进行不同的生成配置并仅在该配置中启用它?然后,您可以选择何时使用它进行构建。