15

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

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

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

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

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

此外,即使在我完全重新安装 Windows 之前,我的旧 Visual Studio 2015 安装中也存在此问题。(当我升级到 Windows 10 时,我确实完全重新安装了 Windows。)

我对任何想法持开放态度,我可能会再次重新安装 Visual Studio 2015以查看问题是否消失。

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

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

另一个更新:打开对话框时,有时 Visual Studio 会完全崩溃。

4

1 回答 1

16

TL;DR: As a workaround for this problem, find your DbContext class which inherit from IdentityDbContext<> and change base class constructor from base("DefaultConnection") to base("DefaultConnection", false) and do a full rebuild on your solution. That will disable checking against Entity 1.0.0 which causes timeouts when run from Publish Web.

The results of debugging: After much debugging, we found the root cause.

  1. When you run Publish Web with Code-First used in your project, it will want to enumerate available connection strings in order to detect your Databases.
  2. To do that, it will call your DbContext class, locating it with reflection and calling it inside VisualStudio's process.
  3. Unfortunately, since it's executed within VisualStudio, ConnectionManager will use devenv.exe.config instead of your web.config, hence your web.config with its connection strings is ignored.
  4. As soon as you call IdentityDbContext<> in the form of base("DefaultConnection"), it will call base("DefaultConnection", true), which (according to the second parameter) will try to detect whether your database uses Identity 1.0.0 schema.
  5. In order to do that, it will try to connect to your database, identified by the name of connection passed to IdentityDbContext<> (usually it will be "DefaultConnection")
  6. Since the web.config is not loaded, the connection string with such name would be unavailable.
  7. For unavailable connection string, Entity would call DefaultConnectionFactory. Again, you can't customize it, as web.config is not loaded. By default, DefaultConnectionFactory will try to connect to .\SQLEXPRESS with Initial Catalog = your connection name, likely resulting in the following connection string:

    Data Source=.\SQLEXPRESS;Initial Catalog=DefaultConnection;Integrated Security=True;MultipleActiveResultSets=True
    
  8. If you do not have SQL Express installed, that will result in SQL exception, which will retry futile attempts to connect until timeout expires.

So, the culprit is Publish Web, which incorrectly runs assembly through reflection without loading the corresponding web.config.



Debugging recipe we have started with: Let's figure what's happening inside.

  1. Make a few dumps during the freeze (let's say a dump every 2-3 seconds). To make a dump, I think the simplest way is this: download & run SysInternals Process Explorer, and use Context Menu on Visual Studio's process | Create Dump | Create Minidump...
  2. Analyze dumps. The simplest way would be to use OSR's instant analyze
  3. Inspect stacks in the dumps (starting from STACK_TEXT in analysis results)
  4. The names of functions on stack can already tell you what's wrong.
  5. If this guide does not help you, I will need to see the dumps myyself. Please be aware that dumps will contain portions of VS's memory, which could contain some personal information, such as file paths.

Update

Now that OSR's analyze failed to analyze the stacks in dumps, it seems we'll have to do it the hard way.

One-time preparation

  1. Install Debugging Tools For Windows as part of Windows SDK (clear all other checkboxes to not install what you don't need)
  2. Run WinDBG (X86) from installed package
  3. In File | Symbol File Path... write

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

Analyzing a dump

  1. In WinDBG, press File | Open crash dump... and open your dump.
  2. In the edit box at the bottom, write !analyze -v and press Enter.
  3. Inspect the stack.
于 2015-10-10T18:00:55.793 回答