I've got some tracing statements with timestamps on an ASP.Net IIS application that gets a lot of traffic. I've got trace statements at the end of Application_BeginRequest and the beginning of Application_PreRequestHandlerExecute in my Global.asax. Occasionally there is a big delay between the end of BeginRequest and the start of PreRequestHandlerExecute, i.e. more than 5 seconds.
What is going on in the lifecycle of an HttpRequest between these two method calls that could be taking so long? This is IIS7 on Windows Server 2008.
Thanks.
If BeginRequest has already happend and the delay is before PreRequestHandlerExecute, you might want to log the thread id. If it is different, you suffer from ASP.NET thread agility.
A reason for this to happen can be the use of sessions. ASP.NET uses a reader-writer lock on the HttpContext.Current.Session. If you write to this variable, all the other request with the same session cannot run concurrently and are parked in a queue. .NET uses a polling mechanism to check whether the session lock is released.
I would also recommend checken that you've build on Release and that system.web/compilation/#debug = 'false'
Related
I have a asp.net web app and few actions are performed using WCF.
My question is -
While my WCF method call is in progress, the application pool is reset due to:
1) Change in Web.Config
2) Some assembly is deployed in Bin Folder
3) IIS Crash
4) IIS Stops
What will happen to my method call?
Things I have tried:
1) Applied Thread.Sleep of 20 Secs in WCF method
2) While the WCF method is in progress, I changed the assembly in bin folder.
Result - Surprisingly, the Success Callback of WCF method is called and the WCF method is called successfully.
As per my expectation, it should go to the Failure Callback.
http://www.iis.net/learn/manage/provisioning-and-managing-iis/features-of-the-windows-process-activation-service-was
In the "Recycling" section
WAS does this by spawning up a new worker process parallel to the old one that is still handling requests. Once the new worker process is up it starts picking up requests from the request queue while the old worker process is instructed by WAS to stop picking up requests. Once the old worker process finishes all executing requests it shuts down. This feature is called "overlapping recycling". It ensures that no requests are lost during a recycle.
I am migrating an app written on asp.net 1.1. There is a process which can take 5 minutes on one page, processing data in SQL, and letting the user know when it's complete.
To get around the HTTP page timeout, the process runs asynchronously and the page refreshes every 5 seconds checking for completion. It's very simple. Here is the problem: I use a session variable as a semaphore to signal process completion.
This is not working now as I cannot read the semaphore set in the asynch process. The asynch process can read the session from the calling routine, but cannot write back.
First, is there a way to get the asynch process to write to a session variable which can be read by another process? This probably is not the best approach today, but getting the app working is my biggest priority.
Second, if I rewrite it, what approach should be used? This is an asp web app. Not MVC.
use callback technologie it allow you to query an operation server side from your client and get a return from server so no session to manage any more:
http://msdn.microsoft.com/en-us/library/ms178210(v=vs.80).aspx
How does IIS handles multiple simultaneous requests to a web service using the same session id when that web service relies on sessions?
If the first web service call has not finished processing, does IIS queue the second web service call temporarily until the first web service call has finished (since they both rely on the same session data).
Or does IIS allow both requests to go forward and any changes made to the session store by the first request immediately affect the second web service call in process even thought that may cause unexpected results.
I believe it is using the first option by queuing the second call until the first is completed due to session reader\writer locks but I have not been able to locate a definitive answer.
Note: In this case the web service requests are generated from the client browser asynchronously.
Yes, like anything else that's using session state, the session state module is going to block the request from going any further down the pipeline (i.e. executing your ASMX web method) until it can aquire the lock to the session. Session state is the enemy of concurrency, avoid it at all costs.
I'm not talking about asynchronous pages or asynchronous handlers, I just want to know if I should be afraid of any side effect when I invoke an asynchronous method that will end after the page is finished rendering.
Example given: Each time that a user do login, I have to launch a heavy and time consuming SQL operation, but the user doesn't need to know the result of that operation, so I can execute the query using BeginExecuteNonQuery without pass any callback, and finish rendering the page.
My concern is, what happen if the HTTP call ends (because the page is served) and whatever I've executed asynchronously is already running? is ASP.NET or IIS going to cut, destroy, void anything?
Cheers.
That operation will run, even when the request has finished. However, please note that the ASP.NET host aggressively kills threads. When IIS has any reason for unloading or recycling the AppDomain, your background thread will be killed. Unloading happens in several situations. For instance when no new requests have come in for a certain period of time. Or when too many exceptions are fired from the application within a certain period of time. Or when the memory pressure gets too high.
If you need the guarantee, that the operation will finish, I think there are three things you can do:
Speed up the operation so that it can run synchronously, or
Move that that heavy operation to a Windows Service and let that execute it, or
You can hook onto the HostingEnvironment.RegisterObject method (as Phill Haack explains here) (demands full trust) to prevent the AppDomain to go down while that thread is running.
If you have a callback registered, the process will comeback to notify the callback otherwise it will still complete the job. AFAIK - neither ASP.NET or IIS will cut/destroy or void anything as the execution was already ordered and it has to complete.
When IIS restarts an ASP.Net (2.0) web application, it can either:
Recycle the AppDomain: Unload the AppDomain and load a new AppDomain on the same process (e.g. when HttpRuntime.UnloadAppDomain() is called, when web.config is changed).
Recycle the process: unload the AppDomain and load a new one on a new process (e.g. when invoking Recycle command on an AppPool via inetmgr, or when memory limit is reached).
Due to some internal reasons (trouble with legacy native code we depend upon), we cannot allow the first option. We just can't load the application twice on the same process.
Can IIS be somehow told to never allow worker process reuse?
I've tried preventing it myself by tracking whether an application has already started on a process once using a Mutex, and if so - throwing an exception during Application_Start()); I've also tried terminating the process by calling Environment.Exit() during Application_End(). The problem with both methods is that it causes any requests that arrive during Application_End or Application_Start to fail (unlike a manual process recycle, which fails absolutely no requests because they are redirected to the new process right away).
I believe that "Recycle the AppDomain" comes under preview of ASP.NET runtime and IIS is not really involved anywhere (I am not 100% sure about this in case of integrated pipeline of IIS7). So I don't think that what you want is feasible. But there are couple of workaround that you may consider for your problem:
Ensure that you run start-up code (manipulating legacy code) to run only once - this should be possible via named system semaphores. Once system semaphore is created by app start-up in worker process, it will exists till process is recycled so you can have per process initialization.
If #1 is not possible then consider hosting code manipulating legacy code in a separate process all together - this process can expose relevant functionality via WCF services over named pipes. ASP.NET will consume them to use legacy code.
Couldn't find a way to tell IIS that worker processes are not to be reused. Can't afford fixing the underlying problem that forbids process reuse. Therefore, ended up calling Environment.Exit(0) in Application_End, although it may cause a small number of requests to fail with a connection reset.