views:

1663

answers:

8

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.

A: 

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
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
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?
ck
A: 

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
Does not apply to ASP.
Bogdan Maxim
+2  A: 

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
A single client, not single computer. Also, some clients completely disregard this.
FlySwat
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
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
@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
@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
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
@unwind, that sounds logical :)
Jeroen Landheer
+2  A: 

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
+10  A: 

THIS IS THE CORRECT ANSWER - edited by asker of question

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.

AnthonyWJones
Sounds plausible.
splattne
I fixed the vote. I can't fix the accepted answer because I couldn't verify when the bounty expired :(
Michael Pryor
@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 <bgrin>
AnthonyWJones
A: 

I have no answer but just noted that Sean Reilly and Leo Moore both refer to ASP.NET which is not ASP...

A: 

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
I tried the integrated/classic setting. No dice on that one.
Michael Pryor
A: 

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