Visual Studio Publish Web Dialogue takes excessive time to load
Asked Answered
D

1

15

Whenever I launch the Visual Studio 2015 Publish Web Dialogue (or Visual Studio 2013, both have the same issue) for a specific project, it takes ~20-30 seconds for it to open. Just as well, when I switch between publish profiles it takes the same amount of time when I switch to a specific one. When I switch to Profile A in the list (from Profile B) it takes the same amount of time as it does when it launches the dialogue itself. When I switch from Profile A to the Profile B it doesn't take any time at all.

Does anyone have any ideas on this? I lose 20-30 minutes a day of development on this issue alone.

I have inspected the XML (.pubxml) on both profiles, and they are identical except for the name of the site on the server, and the Web.config SQL string transformation result. (They both publish to the same server endpoint, both are precompiled with all pages/controls set to one assembly, the only difference is the name of the profile and what the name of the site is.)

I also inspected the profile .user file, and both are identical once again. I am at a loss as to what could be the issue here.

Do note that publishing does not take a lot of time at all. It takes just as long for Profile A to publish as Profile B does.

Also, this issue was present even on my old Visual Studio 2015 installation before I reinstalled Windows completely. (And I did reinstall Windows entirely when I upgraded to Windows 10.)

I am open to any and all ideas, I might reinstall Visual Studio 2015 again to see if the issue goes away.

Further notes: while it is loading the dialogue, it locks Visual Studio up entirely.

Update: reinstalling Visual Studio entirely did not rectify the issue.

Another update: Occasionally Visual Studio crashes completely when opening the dialogue.

Decoy answered 29/9, 2015 at 14:14 Comment(0)
S
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.
Stopple answered 10/10, 2015 at 18:0 Comment(9)
I've done all that, and now it shows what methods/classes/etc are executing, and it looks like the issue is in Entity Framework somewhere. The first items on the MANAGED_STACK section are SQL and Entity Framework lines. Very curious. (The very first line looks like a call to Sleep.)Decoy
Here is a Gist with the MANAGED_STACK information on it, if it helps any. I think there's something up with the SQL stuff it's trying to do.Decoy
I'm going to accept your answer, as it led me to the root problem (there is a SQL exception going on, according to this dump), I really appreciate all the help, effort and insight!Decoy
The exception object is really interesting, and SQL connection timeout, which nicely correlates with freeze you're experiencing.Stopple
Yeah, it happens right in the middle of the freeze, so I'm going to try a few things and see what happens. Again, I really appreciate all the help, I'd have never found this myself. :)Decoy
Do you understand which SQL server is that about? Can you try accessing it directly?Stopple
Let us continue this discussion in chat.Stopple
regarding your TL;DR: I don't have any Context, which inherits IdentityDbContext, just DbContext itself is inherited. Also I use base("conncectionString"), which is not overloaded by base(String, Boolean). Is there a workaround for that constellation? (EF 6.1.3)Eyeful
It's been a while. Please post a new question, providing code snippets for what you said, and cross-link these two questions. You will probably get help sooner then I'm able to look into it.Stopple

© 2022 - 2024 — McMap. All rights reserved.