我最近刚刚下载并安装了 Visual Studio Professional 2015 (14.0.23107.0)。我第一次打开我们的解决方案(28 个项目)并执行 Build -> Rebuild Solution 时,我的开发机器完全爬行了。 CPU 已达到 100% 的最大值并且构建从未完成 - 即使在 > 10 分钟之后。
我打开 Windows 任务管理器并注意到:> 10 个 VBCSCompiler.exe 任务正在运行。合并后,这些任务将 CPU 发送 > 90%。
知道为什么有这么多任务在运行吗?有什么办法可以阻止这种情况发生?
这是我能找到的与遇到相同问题的其他人最接近的事情:https://github.com/dotnet/roslyn/issues/2790
更新 (8/7)
- 汉斯·帕桑特,好主意。我的经理为我提供了此版本 (14.0.23107.0)。这是“正式发布”的正确版本吗??我没有故意安装任何 Visual Studio 2015 的每个发布版本。我认为没有任何测试版。
-Kyle Trauberman,我不太熟悉 Visual Studio 上下文中的环境变量;但是,我天真地在 VS(和 MSBuild)命令提示符窗口中运行了 set DisableRosyln=true
。这似乎没有任何影响。即使在重新启动 VS2015 后,VBCSCompiler.exe 也显示正确备份。
我修复了 VS2015 安装并重新启动。这没有帮助。
更新第 2 部分 (8/7)
-Hans Passant,写得非常令人印象深刻!!虽然这次没有出现这个问题,但我看了一下你描述的事情:
至于加载了 VBCSCompiler.exe 的模块,这是我所拥有的:
有趣的是,我们的 .NET 核心程序集处于不同的版本。你在 4.06.79 而我在 4.06.81。
我的“客户端 dll”(位于 C:\Program Files (x86)\MSBuild\14.0\Bin\Microsoft.Build.Tasks.CodeAnalysis.dll)与您的版本和时间戳相同:
奇怪的是,当我查看 ILSpy 中的代码时,我看到了一些稍微不同的东西——也许是优化?
private static NamedPipeClientStream TryAllProcesses(string pipeName, int timeoutMs, CancellationToken cancellationToken, out string newPipeName)
{
string str = pipeName;
int num = 1;
while (File.Exists(string.Format("\\\\.\\pipe\\{0}", pipeName)))
{
NamedPipeClientStream result;
if ((result = BuildClient.TryConnectToProcess(pipeName, timeoutMs, cancellationToken)) != null)
{
newPipeName = pipeName;
return result;
}
pipeName = str + "." + num.ToString(CultureInfo.InvariantCulture);
num++;
}
newPipeName = pipeName;
return null;
}
**让我回到传递给 VBCSCompiler.exe 实例的特定 pipname 参数上。我将不得不等到它再次发生。
最佳答案
嗯,没有明显的重现场景,也没有其他人对此提示。您的解决方案并不罕见。将 cpu 固定到 100% 并让 VBCSCompiler 进程吞下 ~1.5 GB 在大型项目中并不是很难,但当我看着我的项目时,它非常干净。
第一个可能的失败场景是您有一些未安装的测试版,这是一个非常常见的问题。使用调试器进行查看。使用 Debug > Attach to Process 并选择一个正在运行的实例。然后 Debug > Break All 和 Debug > View > Modules。注意版本号和时间戳,它们应该是这样的:
请注意,有意隐藏了一些列以使其可读。时间戳是 CST 时区。
那是服务器端。存在您发现的错误的客户端位于 C:\Program Files (x86)\MSBuild\14.0\Bin\Microsoft.Build.Tasks.CodeAnalysis.dll。看看它的属性,我的是 85,192 字节,创建于 2015 年 6 月 21 日星期日,下午 7:06:54,文件版本号 1.0.0.50618。您可以使用 Reflector 或 ILSpy 等反编译器查看该文件,导航到 BuildClient.TryAllProcesses()。与错误修复相关的行是:
for (int i = 1; File.Exists(string.Format(@"\\.\pipe\{0}", pipeName)); i++)
错误版本缺少
\\.\pipe\
。请注意,上面的代码片段中的错误检查非常不充分,File.Exists() 由于多种原因返回 false。这也是没有更早发现错误的基本原因。这会启用几种可能的故障模式,如果您的机器被程序员自愿安装的典型收缩包装恶意软件感染,则会启用这种故障模式。服务器和客户端代码通过具有特殊名称的命名管道相互连接。您可以在任务管理器的进程选项卡中看到的内容。使用“ View ”>“选择列”(Win8 及更高版本:右键单击列标题)并勾选“命令行”选项:
请注意
-pipename
参数。如果 File.Exists() 调用返回 false,则 MSBuild 将再次启动 VBCSCompiler.exe。如果您看到所有这些实例都使用相同的 -pipename 参数运行,那么您的计算机上运行的软件会干扰正常命名管道的使用。您首先要考虑的是寻找一种不太激进的反恶意软件解决方案。您可以编写一个使用 System.IO.Pipes 命名空间的小测试程序来获得更好的异常消息。关于c# - VBCSCompiler.exe 的大量实例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31708758/