Visual Studio 发布网络对话加载时间过长

Visual Studio Publish Web Dialogue takes excessive time to load

每当我为特定项目启动Visual Studio 2015 Publish Web Dialogue(或Visual Studio 2013,两者都有相同的问题)时,它需要大约需要 20-30 秒才能打开。同样,当我在发布配置文件之间切换时,它花费的时间与我切换到特定的配置文件 所花费的时间相同。当我(从配置文件 B)切换到列表中的配置文件 A 时,它花费的时间与它启动对话本身时花费的时间相同。当我从配置文件 A 切换到配置文件 B 时,根本不需要任何时间。

有没有人对此有任何想法?仅在这个问题上,我每天就损失 20-30 分钟的开发时间。

我检查了两个配置文件上的 XML (.pubxml),除了服务器上的站点名称和 Web.config SQL 字符串转换结果。 (它们都发布到 相同的 服务器端点,都预编译所有 pages/controls 设置为一个程序集,唯一的区别是配置文件的名称和网站是。)

我还检查了配置文件 .user,两者完全相同再次。我不知道这里可能是什么问题。

请注意,发布根本不会花费很多时间。配置文件 A 的发布时间与配置文件 B 的发布时间一样长。

另外,在我完全重新安装 Windows 之前,这个问题甚至出现在我旧的 Visual Studio 2015 安装中。 (当我升级到 Windows 10 时,我确实完全重新安装了 Windows 。)

我愿意接受所有想法,我可能会重新安装 Visual Studio 2015 再次 看看问题是否消失。

进一步说明:在加载对话时,它会Visual Studio完全

更新:重新安装 Visual Studio 完全没有解决问题。

另一个更新:偶尔Visual Studio打开对话时完全崩溃。

TL;DR: 作为此问题的解决方法,找到继承自 IdentityDbContext<>DbContext class 并更改基础 class 构造函数从 base("DefaultConnection")base("DefaultConnection", false) 对您的解决方案进行完全重建。这将禁用对 Entity 1.0.0 的检查,这会在 运行 来自 Publish Web 时导致超时。

调试结果:经过多次调试,找到问题根源

  1. 当您 运行 在您的项目中使用代码优先发布 Web 时,它会想要枚举可用的连接字符串以检测您的数据库。
  2. 为此,它将调用您的 DbContext class,通过反射定位它并在 VisualStudio 的进程中调用它。
  3. 不幸的是,由于它是在 VisualStudio 中执行的,ConnectionManager 将使用 devenv.exe.config 而不是您的 web.config,因此您的 web.config 及其连接字符串将被忽略。
  4. 一旦您以 base("DefaultConnection") 的形式调用 IdentityDbContext<>it will call base("DefaultConnection", true), which (according to the second parameter) will try to detect 您的数据库是否使用 Identity 1.0.0 架构。
  5. 为此,它会尝试连接到您的数据库,由传递给 IdentityDbContext<> 的连接名称标识(通常是 "DefaultConnection"
  6. 由于未加载web.config,具有该名称的连接字符串将不可用。
  7. 对于不可用的连接字符串,实体将调用DefaultConnectionFactory。同样,您无法自定义它,因为未加载 web.config。默认情况下,DefaultConnectionFactory 将尝试使用 Initial Catalog = 您的连接名称连接到 .\SQLEXPRESS,可能会导致以下连接字符串:

    Data Source=.\SQLEXPRESS;Initial Catalog=DefaultConnection;Integrated Security=True;MultipleActiveResultSets=True
    
  8. 如果您没有安装 SQL Express,将导致 SQL 异常,它将重试无用的连接尝试,直到超时到期。

所以,罪魁祸首是 Publish Web,它错误地 运行 通过反射组装而没有加载相应的 web.config



我们开始的调试方法: 让我们看看里面发生了什么。

  1. 冻结期间进行一些转储(假设每 2-3 秒转储一次)。要进行转储,我认为最简单的方法是:下载 & 运行 SysInternals Process Explorer,然后使用 Context Menu on Visual Studio's process | Create Dump | Create Minidump...
  2. 分析转储。最简单的方法是使用 OSR's instant analyze
  3. 检查转储中的堆栈(从分析结果中的 STACK_TEXT 开始)
  4. 堆栈上的函数名已经可以告诉你哪里出了问题。
  5. 如果本指南对您没有帮助,我需要亲自查看转储。请注意,转储将包含部分 VS 内存,其中可能包含一些个人信息,例如文件路径。

更新

既然 OSR 的分析未能分析转储中的堆栈,看来我们将不得不采取艰难的方式来完成它。

一次性准备

  1. 安装 Debugging Tools For Windows 作为 Windows SDK 的一部分(清除所有其他复选框以不安装您不需要的东西)
  2. 运行 WinDBG (X86) 来自安装包
  3. File | Symbol File Path...中写入

    srv*C:\Symbols*http://msdl.microsoft.com/download/symbols
    
  4. File | Save workspace

正在分析转储

  1. 在 WinDBG 中,按 File | Open crash dump... 并打开您的转储。
  2. 在底部的编辑框中,输入!analyze -v并回车。
  3. 检查堆栈。