ASP.NET precompiled but still slow startup time? - asp.net

I'm trying to figure out what I'm doing wrong or not understanding. I have a solution with a web application and a few class libraries.
I edited the web app publish settings of the web project. It has "precompile this application before publishing" checked and I've selected "Only files needed to run this application".
I created a publish profile which just dumps it to a folder. From that folder I upload (using FTP) the DLLs to a staging site I have setup which is where I do final testing before deploying the app live. After uploading the DLLs and going to the staging site there's still an app startup delay, which seems just as slow. Isn't that supposed to be gone by precompiling?
Edit: Turning off allowing the site to be updatable fixes the problem. Allowing it to be updateable causes all of my ASPX pages and user controls to be compiled on first page view which is causing there to still be a delay even though the code behind is compiled. I've disabled batch compiling and turned on optimizeCompilations in the web.config and now it's fast:
<compilation batch="false" optimizeCompilations="true" />

Maybe you have left debug=True setting in config?
This will, among other things, disable batch compiling and caching (but caching should not affect your startup time).
See here and here for more details.

Which Framework version are you on? If you are on .Net 3.5 (specifically), you should consider using:
<configuration>
<runtime>
<generatePublisherEvidence enabled="false"/>
</runtime>
</configuration>
It will approx half the cold-start time. But it is a known issue that when IIS do a cold-start on an application, there is an initial delay. This is not limited to you deploying the application, but also when your application pool recycles.
So far, the best option that I can think of is to write a scheduled-script to automatically spin-up (warm up) a site periodically (say every 1min?).

I managed to figure mine out. Previously my cold start was taking 18 minutes on my local dev machine (on staging it was less than 30s).
I finally noticed that a program was running high CPU during the cold restart.
The program was.. MsMpEng.exe - This is Microsoft Security Essentials including Microsoft Defender.
I uninstalled it and my site now loads on less than 30 seconds.
Obviously it was scanning each .dll being copied during the cold start, and blocking each additional .dll from being copied until it was finished scanning the previous one.
Cold start is now less than 30s.

In our case the precompiled app (that was previously updated in a blink of an eye) started behaving slowly after we added SignalR.
Now, I profiled the process using this open source tool (disclaimer, I'm a contributor to the project, originally written by the Stackoverflow team), and I saw this among the longest call stacks:
//...skipped
System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start
Microsoft.Owin.Host.SystemWeb.OwinCallContext.AcceptCallback
//...skipped
Thanks, Obama.
Wtf, Microsoft?
Say hello to Owin dependency.

Related

IIS deletes System.Web.Extensions.dll, why?

I moved a site to another server, it worked fine for a a while, but then crashed. I figured out that System.Web.Extensions.dll was missing, so I copied it again. After a while it was missing again.
Using Process Monitor I figured out that IIS (w3wp.exe) deletes the file soon after I copy it to the bin folder. (CreateFile with "Read Attributes, Delete" access.)
What could cause this behaviour?
This is extremely difficult to diagnose without version or error information, but I can offer a few suggestions.
First of all, it is not recommended to put System.Web.Extensions in the bin folder. If the latest framework is installed, the ajax assemblies are included in the GAC and everything is configured to work properly. By dumping a dll in the bin folder, you are experimenting with version, dependency and trust issues which may cause your application to run slower, different or not at all.
Verify your .net framework installations to ensure the most recent version or service packs are installed on both the server and your development machine. Then double check which versions are actually being referenced by your web project and web.config. There has always been a version problem with ajax between development and deployment (expecially during beta cycles) but as far as why the IIS worker process deletes files in this scenario, you have me stumped.

How to avoid publishing ASP.NET applications in debug mode from Visual Studio?

We all know that we should only be publishing our ASP.NET Web Applications with release build type, so why do I not get a warning when I trigger the "Publish" command in Visual Studio 2008, for a project configured to build in debug mode?
Sure, there might be cases where I need to publish a debug build to a development or test environment, but answering yes in a confirmation dialog would be acceptable in these cases. Is there an option that I have overlooked, forcing Visual Studio to warn me every time I try to publish a debug build?
Yes, we could just ban using the "Publish" command and use a more solid build management tool, but this involves a change of process and might not be an option in this particular case.
Typically things like this are handled in an automated build tool. Quite frankly, I publish to a dev site by orders of magnitude more often than I do to production.
For that reason alone having an extra dialog box in the process would be a bit maddening.
Further, even without a build system in place, most people have different config files for the different environments and for the most part handle it with a web.config setting.
I use Publish to build and publish my development sites to the dev servers all the time, a question about this would just be irritating in my opinion.
I think the issue here is one of your personal process rather than the tool. Production releases should be far less frequent and would require you to change the location the site is being published to, if you remember to change that then it's not too much to also expect that you are publishing the correct build type.
You can set deployment retail="true" in your production server machine.config to stop worrying about it
<configuration>
<system.web>
<deployment retail="true"/>
</system.web>
</configuration>
Tip from Scott Guthrie's article Don’t run production ASP.NET Applications with debug=”true” enabled

How can I tell IIS to compile specific folders independently of the rest of my Web site?

Is there any way to get ASP.Net to compile different folders independently?
I have a Web app that uses some commercial software. The admin UI for this software is in a single folder -- there are about a 1,000 files in there, all told. (I've looked through it -- it ain't the greatest code ever written...)
This folder takes forever to build. If I build explicitly, it...slowly...compiles..subfolder...after...subfolder... If I do the site as a Web site project (as opposed to a Web application project -- so no explicit build), I have waited up to four or five minutes to refresh a page on a simple code change.
Sometimes it just gets stuck -- I'll be waiting and waiting and I'll just hit F5 for giggles, and -- bam! -- there it is. It apparently compiled sometime in the last 10 minutes but forgot to tell the browser about it...
How do I get this folder out of the general compilation? I never change anything in here, and I wish ASP.Net would just compile the friggin' thing to an assembly and leave it alone.
Possible?
Why don't you use aspnet_compiler to precompile the application? It does work on Web site projects as well as Web application projects and it can precompile almost everything in an ASP.NET app.
Maybe this is too obvious, but... Pull out that folder and create a separate website project for it with its own web.config.
You definitely can't have IIS treat the folders differently without that... it's the ASP.NET engine that handles the on-the-fly compilation, IIS knows nothing about it.

Why IIS Development server recompiles all my web application every time I build my webapp in VS 2008?

We have a web application project (not a web site), until the day we have added batch="false" to web.config web development server was compiling all the web application instead of the page that was requested.
<compilation debug="true" batch="false">
<assemblies>
...
</assemblies>
</compilation>
This make us faster. But I don't know what changed (I have inspected both foo.cproj and web.config from repository, comparing older versions but find nothing can cause this slowness).
I looked at %temp%/Temporary ASP.NET Files; after I compile my web app (not recompile, shift + f6), then I request a page and I see that web server deletes all of already compiled files from %temp%/Temporary ASP.NET Files and recreates. I don't know if this is normal but it seemed to me a full recompilation of all web app, which is very slow. (I looked via process explorer to wevdev.wevserver.exe it calls csc.exe several times)
How can I can make compilation faster? Thanks...
There is an option for ASP.NET Development Server named 'Enable Edit and Continue' that is available with the 32-bit version of NET CLR. Turn that off in Visual Studio.
Also, try changing the build for 'Any CPU' in a build for 'x86'. That should make compilation faster.
I believe this is a part of using the Web Application Project. Any time you build your application, the entire site is recompiled. You should see that unlike a 'Web Site', the web application all compiles down to a single dll (plus references).
Another thing you have to watch out for is any time you delete a file/folder under your root web app folder it will also force a recompile, which can be a real pain in the butt for temporary files.
On the plus side once you get over the first compile, there will be no additional waiting for compile times on unvisited pages.

How to make the process of debugging ASP.NET Sharepoint applications less time consuming?

I'm comparing it Java where you can start your application server in debug mode, then attach your IDE to the server. And you can change your code "on the fly" without restarting the server. As long as your changes don't affect any method signatures or fields you can just hit recompile for a class and the application server (servlet container) will reload the class.
I suppose this is impossible in ASP.NET since all classes are packed into assemblies and you cannot unload/reload assemblies, can you ?
So when you have an .aspx page and an assembly deployed to GAC and your codebehind changes you have to redeploy the assembly and reset IIS. I'm talking about Sharepoint applications in particular and I'm not sure whether you have to do iisreset for private assemblies but I guess you have too.
So the best way to debug aspx pages with code behind I guess would be to get rid of the codebehind for the time of active debugging and move into the page, then when it is more or less working move it back to codebehind. (This would be applicable only for application pages in Sharepoint, site pages don't allow inline code )
How do you approach debugging of your ASP.NET applications to make it less time consuming?
From Matt Smiths blog on how to get F5 debugging with sharepoint. A very cool trick.
Create a web application project in Visual Studio (File -> New -> Project -> ASP.Net Web Application, not File -> New -> Web Site).
Move the .csproj and .csproj.user files, along with the Properties folder, into C:\inetpub\wwwroot\wss\virtualdirectories\, where is the name or number of the web application corresponding to the SharePoint site you'd like to debug on.
Attach the project to an existing solution (e.g. STSDEV project).
Set as startup project (right-click project name, "Set as Startup Project").
Access project properties (right-click project name, "Properties") and click
Under the "Servers" setting, click "Use IIS web server", then enter the URL to the SharePoint web application you want to debug on, e.g. http://mymachine:99.
Yes private assemblies DO NOT require reset of the IIS. So you should just to xcopy new version to the application's Bin directory and refresh the page (e.g. by VS post build event as I did).
But there are some trade offs. You should decrease trust level in application web.config file:
<system.web>
...
<trust level="WSS_Medium" originUrl="" />
...
</system.web>
By the way. I do not suggest to deploy like this. It's just workaround for comfort write-test-debug cycle length.
If you are using the GAC, you can at least do iisapp.vbs /a "App Pool Name" /r instead of iisreset (it's quicker to recycle a single app pool than to restart IIS).
First, develop on a computer running SharePoint. Preferably, this means running Windows Server 2003 on Virtual PC or VMWare. This will let you deploy and debug SharePoint code directly, rather than having to copy files between servers and use the remote debugger.
Use a VS add-in to simplify the process of deployment and debugging. I've been using WSPBuilder but I think there are others out there. WSPBuilder has commands to deploy solutions, package them as WSPs, and attach your debugger to the local IIS process. It won't allow you to add/remove assemblies on the fly, but you can set breakpoints and run code through the Immediate window in VS.
Depending on how your production server is configured, it's usually a good idea to develop on a server with full/trust security settings, including disallowing code blocks in ASPX files. This makes debugging a little more difficult, but it reduces the number of nasty surprises you'll have when your code is finally deployed to production.
And you can change your code "on the fly" without restarting the server
You can accomplish this with ASP.net if you make a Web Site project (as opposed to a Web Application Project). Using a Web Site project, you can post changes to code-behinds without having to refresh anything on the server, and the server does the compile work for you on all code changes. See here for more info on this.
This should also solve your difficulties with deploying the assembly to the GAC. As the server handles all compilations for Web Site projects, you wont have to redeploy any assemblies when changing files.
Use an automated testing framework (NUnit) to write integration tests. This won't work for everything, but of course, it depends on what you're testing.
If you also have TestDriven.NET installed, you can run individual tests with the debugger. This has been helpful.
WSPBuilder Extensions has a "deploy to GAC" shortcut, unfortunately it never works for me. But it's a really quick way to code->compile->test.
If you're not using WSPBuilder Extensions, you can instead open a command prompt and run
gacutil /u yourassemblynamegoeshere
gacutil /i yourdllgoeshere.dll
If you do this often, you can put it in a post-build event or in a batch file. Also, I'm unclear whether the gacutil /u (to remove the DLL first) is necessary.
What it seems like you're trying to do is tell Sharepoint "When I start debugging in Visual Studio, use the version of the DLL that was compiled in the project's /bin/debug directory instead of the version of the DLL that is registered in the GAC." I haven't solved that problem, but here is how I debug Sharepoint.
A developer machine is Win2008, IIS 7, MOSS 2007, VisStudio 2008, and WSP Builder installed. Inside VS2008, a button is added to attach to w3p.exe process, Andrew's HOWTO attach to w3p
The solution file has two projects:
* First project is the .WSP that deploys all the app pages, including the DLL. Use WSPBuilder menu items for handling the .WSP creation and deployment.
* Second project is for the DLL behind the pages.
If you want the DLL to be copied to the GAC regularly, add a post-build event to the DLL's project that copies from /bin/Debug to the GAC. But, these days, I find I have just been recompiling the solution and then deploying the .WSP using the menu items, and then starting up the debugger using the button. It takes me an F-key and 3 clicks and about a minute for most of my projects, but I suppose it could be quicker.

Resources