我最近刚刚下载并安装了 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 的模块,这是我所拥有的:

c# - VBCSCompiler.exe 的大量实例-LMLPHP

有趣的是,我们的 .NET 核心程序集处于不同的版本。你在 4.06.79 而我在 4.06.81。

我的“客户端 dll”(位于 C:\Program Files (x86)\MSBuild\14.0\Bin\Microsoft.Build.Tasks.CodeAnalysis.dll)与您的版本和时间戳相同:
c# - VBCSCompiler.exe 的大量实例-LMLPHP

奇怪的是,当我查看 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。注意版本号和时间戳,它们应该是这样的:

c# - VBCSCompiler.exe 的大量实例-LMLPHP

请注意,有意隐藏了一些列以使其可读。时间戳是 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 及更高版本:右键单击列标题)并勾选“命令行”选项:
c# - VBCSCompiler.exe 的大量实例-LMLPHP

请注意 -pipename 参数。如果 File.Exists() 调用返回 false,则 MSBuild 将再次启动 VBCSCompiler.exe。如果您看到所有这些实例都使用相同的 -pipename 参数运行,那么您的计算机上运行的软件会干扰正常命名管道的使用。您首先要考虑的是寻找一种不太激进的反恶意软件解决方案。您可以编写一个使用 System.IO.Pipes 命名空间的小测试程序来获得更好的异常消息。

关于c# - VBCSCompiler.exe 的大量实例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31708758/

10-15 05:40