18

Situation: Classic ASP application, using a custom Application Pool. Default settings.

On some IIS7 machines, IIS decides to serve only one page at a time. So if multiple load any pages from a site, each one has to load in succession.

e.g. If I load http://foo.com/default.asp from one browser, and from another machine I load http://foo.com/differenturl.asp, the first has to finish before the other will load. It's almost like the w3p process is single threaded.

Note, there is a setting called MaxProcesses in the Advanced Settings for IIS that says "Set this to greater than 1 to create a Web Garden" (whatever that is). This does NOT solve the problem because this spawns multiple processes with their own session state etc, and when you load http://foo.com/default.asp there's no way to guarantee you get assigned to the same process.

The problem revealed itself because we have a diagnostic page which is written in ASP that creates and ActiveX control which loads a url on the website and returns the results.

So, diagnostics.asp loads and in the code on the server side it creates a small web control that loads (think XMLHTTP control) default.asp on the same server.

This page will NEVER finish loading, because the server is waiting for the diagnostics.asp page to finish before it serves the default.asp page. Deadlock!

This works fine on every IIS6 machine out there, and I believe there are some IIS7 servers where it works fine too.

I've verified it's not a result of our quirky diagnostic either. Loading multiple tabs from one machine, or even separate machines will show that the web process handles them one at a time.


Correct Answer by AnthonyWJones: Server Side debugging was turned on in IIS7. This puts IIS into single threaded mode.

hlovdal
  • 26,565
  • 10
  • 94
  • 165
Michael Pryor
  • 25,046
  • 18
  • 72
  • 90
  • crossposted here http://forums.iis.net/p/1155632/1894991.aspx#1894991 – Michael Pryor Feb 26 '09 at 17:06
  • Could you write which part of the selected answer helped? What was the reason behind the problem? – Tomek Szpakowicz Mar 11 '09 at 22:24
  • I will when I find out. I don't know yet since I can't repro on my machine, just one customer (and he's on vacation). – Michael Pryor Mar 12 '09 at 20:28
  • OK. Since you've marked the answer, I thought you've worked it out. When you do, please share... I'm just curious. As I said I've problems running some old ASP code on IIS7 myself (sessions, load balancing, authentication, all of it goes crazy). Wish I could rewrite it in ASP.NET. – Tomek Szpakowicz Mar 18 '09 at 17:39
  • I didn't mark the answer, Stackoverflow did because I put a bounty on the question and it auto selects an answer. My suspicion is that IIS is in debug mode and so is operating single threads. – Michael Pryor Mar 18 '09 at 18:15
  • Michael did you not see my answer? Strangely it was voted down yesterday, despite being posted before the end of the bounty period. – AnthonyWJones Mar 19 '09 at 08:09

8 Answers8

32

In IIS manager click on the application in the tree.

Double click ASP under the IIS section.

Expand "Debugging Properties"

Ensure both "Enable Client-side Debugging" and "Enable Server-side debugging" are set to false.

When debugging is enabled ASP is limited to processing one request at a time in a single threaded manner.

eliah
  • 2,267
  • 1
  • 21
  • 23
AnthonyWJones
  • 187,081
  • 35
  • 232
  • 306
  • I fixed the vote. I can't fix the accepted answer because I couldn't verify when the bounty expired :( – Michael Pryor Mar 19 '09 at 17:48
  • @Michael: thanks for the recognition the votes are fine. I recognize that people such as you have a life and therefore better things to do than keep track of whats going on on SO all the time like some of us – AnthonyWJones Mar 19 '09 at 18:24
5

First of all: Make sure you test this with multiple clients. A single computer makes only 2 HTTP requests at the same time to the same server (IP adress). (This is an RFC speficiation.)

If that does not resolve your problem, take a look in IIS7 -> ASP -> Services -> COM Plus Properties -> Execute in MTA. Try to set this setting to "True".

Hope this helps.

Jeroen Landheer
  • 9,160
  • 2
  • 36
  • 43
  • 1
    A single client, not single computer. Also, some clients completely disregard this. – FlySwat Mar 09 '09 at 23:46
  • 1
    The asp/comPlus/executeInMTA property in IIS7 is the same as AspExecuteInMTA in IIS6. It's 0 by default. If it wasn't set to 1 in IIS6, it probably won't help in 7. Anyway, one should be careful with this setting, as some COM objects might misbehave in multi-threaded environment. – Tomek Szpakowicz Mar 11 '09 at 01:28
  • True that some COM+ components can misbehave when they are not designed for a multithreaded environment. Nevertheless it can be that your ASP pages just "hang" on this issue so it might not hurt to try. – Jeroen Landheer Mar 11 '09 at 03:08
  • @FlySwat: Yes, I know that this is the case, though I'm not sure if IIS7 enforces this on the server side (i.e. per client IP address.) It's easy to get 2 connections simultaniously on a single HTTP page (e.g. images), so it never hurts to check from 2 physical PCs. – Jeroen Landheer Mar 11 '09 at 03:10
  • @Jeroen Landheer: My point wasn't that executeInMTA is dangerous. It just is off in IIS6 as well and it works. IIS runs ASP requests in multiple threads anyway. If your ASP code works in Multi-Threaded Apartment or not, is a completely different thing. – Tomek Szpakowicz Mar 11 '09 at 12:39
  • 1
    If IIS7 enforces that based on client IP alone, it'll not be very nice if accessed by multiple users behind a NAT/Firewall kind of thing. Sounds unlikely, but what do I know. – unwind Mar 11 '09 at 12:58
  • @unwind, that sounds logical :) – Jeroen Landheer Mar 11 '09 at 18:00
2

Are you sure you don't have a dependency in your code which is causing the deadlock. I've seen this before where logging, sql connections etc creates a dependency. Use perfmon and check the hard disk read/write queue, memory read/write queue to see if things are backing up.

I would highly recommend Tess Ferrandez's (ASP.NET Escalation Engineer - Microsoft) blog for lots in insights and way to find out what is happening. Tess has forgotten more about this stuff than most people will ever know.

I think your problem is not IIS related but something in your app, probably in your ActiveX component. Make sure you clean up after your ActiveX component. Here's a piece of code I use to clean up after using Excel (Another Com component). Remember Com is not managed.

    Private Sub ShutDownExcel()
    If objExcel IsNot Nothing Then
        objExcel.DisplayAlerts = True
        objExcel.Quit()
        System.Runtime.InteropServices.Marshal.ReleaseComObject(objExcel)
        objExcel = Nothing
    End If

    ' Clean up memory so Excel can shut down. 
    GC.Collect()
    GC.WaitForPendingFinalizers()

    ' The GC needs to be called twice in order to get the 
    ' Finalizers called - the first time in, it simply makes 
    ' a list of what is to be finalized, the second time in, 
    ' it actually the finalizing. Only then will the 
    ' object do its automatic ReleaseComObject. 
    GC.Collect()
    GC.WaitForPendingFinalizers()
End Sub

Hope this helps.

Leo Moore
  • 2,118
  • 2
  • 19
  • 21
1

Have you changed "Managed pipelined mode" on Application Pool to "Classic" (default is "Integrated")? If not, try with classic.

I don't know if it would help in any way. I have long ago ceased to fight to get classic ASP apps to work with IIS7. (Not that I can say, the apps are truly nice and correct, but they worked in earlier versions.)

And try turning buffering off for test pages and make them spit something out in each iteration. Buffering (and caching) might've changed in IIS7. Maybe they are processed concurrently after all and simply buffers are too big to see the difference.

That's all that comes to my mind right now.


I assume you are testing with very simple case. Your app doesn't (neither test pages nor global.asa) use any strange objects that are common to both requests and so need locking.

Tomek Szpakowicz
  • 14,063
  • 3
  • 33
  • 55
  • I tried the integrated/classic setting. No dice on that one. – Michael Pryor Mar 11 '09 at 18:24
  • I can confirm this fixed an issue I was having with sessions just poofing randomly. Sometimes user could work for an hour no problem, other times, one click and they were logged out for no reason ... classic mode is required if you aren't doing .NET .... – easleyfixed Jun 02 '22 at 14:33
0

If it isn't an issue with the debug settings, I've found that you can experience similar behavior when using session variables in ASP in IIS 8.

I don't know that this is IIS 8 specific, but "ASP guarantees that only one request from a Session will be executing at any time." http://msdn.microsoft.com/en-us/library/ms972335.aspx

expdiant
  • 1,180
  • 1
  • 7
  • 8
0

IIS7 is most certanly multi threaded, so I would guess there is a problem with your app.

You mentioned ActiveX to load a page from same server - maybe this ActiveX isn't free threaded and this causes every page that uses it to run single instance?

BTW: Web Garden - same server useing multiple processes - cannot use inprocess session Web Farm - multiple web servers

bh213
  • 6,343
  • 9
  • 43
  • 52
  • 1
    Problem is still there when you make two asp pages with loops in them (so they execute for awhile). IIS7 won't display the second page until the first page finishes, so it's not a problem with the app. – Michael Pryor Feb 26 '09 at 15:05
  • That doesn't eliminate it being a problem with the app, it is more likely to be a problem with the the app. have you tried manually hitting two URLs at the same time? – cjk Mar 10 '09 at 19:43
0

Ensure that asp.net is configured to use more than 1 worker thread. This msdn article explains how to set this configuration option.

Sean Reilly
  • 21,526
  • 4
  • 48
  • 62
0

Just a thought but if you go to the website in IIS, click the Limits... link on the left, what are the connection limits set to? There is both a max bandwidth and max concurrent connections options there.

I would also go to the App Pool and click Advanced Settings... and check the CPU and Memory limits. Possibly even creating a new app pool from scratch with No Managed Code selected to eliminate it.

Robert MacLean
  • 38,975
  • 25
  • 98
  • 152