Consider the following code which runs in an ASP.Net web application on IIS...
_thread = new Thread(Method1)
_thread.Start();
As there is a thread pool within the ASP.Net process what is the effect of this code? Specifically...
Will it take another thread from the ASP.Net thread pool? Or from a different threadpool? Or does this code bypass the thread pool and just get a new thread?
Is this the same thread pool that is used to serve page requests? Therefore, this code which was put in to improve performance could actually reduce it by taking another thread that could be used to serve another resource to another user?
Is the thread pool only used for serving non-static resources? Does IIS have it's own thread pool for serving resources that do not run through the managed pipeline?
What would happen if the App. Pool was recycled after calling _thread.Start()? Would IIS allow this thread to complete before closing down the application pool?
It seems to be that this code forces the creation of a new thread. Would there be a benefit to swapping this code to use Async/Wait? The code that runs in Method1() is IO bound.
When you call new Thread explicitly, that thread is not part of the thread pool. You are fully on your own.
The so called ASP.NET thread pool is purely used to process request messages (to host HttpApplication derived objects).
Static files are served by IIS natively, so the ASP.NET thread pool is for ASP.NET contents only. But here you should notice all happens inside the worker process (w3wp.exe). Just some are processed by native components, while others are by managed components. The pipeline is unified if you are using the integrated pipeline mode.
Application pool recycle only waits for requests to be processed. Your own threads will be killed when all requests are done.
Async/await does not create threads automatically. But by switching to async/await, you do avoid create a thread, and that should help improve performance.
ASP.NET 4.5+ (the one where you can use async-await) uses the same thread pool to handle requests and to schedule task execution through Task.Run.
When you use Task.Run when handling an ASP.NET request, you'll be changing context to a new thread pool thread and returning the current thread pool thread back to the thread pool. When the task completes, you'll be switching back another thread pool thread.
Using Task.Run when handling an ASP.NET request requires, at least, one more thread pool thread and incurs in, at least two context switches.
The bottom line is that it requires more resources and takes more time to handle the request.
Related
I've been reading a lot about how IIS manages threads for http requests (taking them from the pool once needed and "releasing" once the request has been processed)...
And about the whole concept of async requests in, for example, ASP.NET MVC that are used to "release" threads back to the pool when long-wait I/O operations are executed on the side.
But what I can't understand is - if I start "normal" threads using Thread.Start() - these threads are "unpooled", right? And they don't use up the IIS request thread pool - is this correct?
I tried Googling but can't find the exact answer. I know that Thread.Start does not use the .NET's built-in ThreadPool at all - but I have doubts about IIS using the same mechanisms for its request threads, could it be that IIS "request pool" is different from the .NET's ThreadPool and uses some lower level pool, so that my Thread.Start will also end up there?
I guess what I'm asking is - is there a limit on Thread.Start() in an ASP.NET app and can a lot of Thread.Start's block my web application during a high load because of thread-queuing?
UPDATE: found this answer but it does not explain why and what happens: Why ASP.NET kills my background thread?
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.
My undersatnding on ASP.Net is when a request comes, ASP.Net uses a internal thread from thread pool to do the work and respond. Correct me if I am wrong. If that is the case, will I able to get a control on this asp.net thread pool?
You cannot interact with the thread pool directly though. However, you can manipulate some of the characteristics of the thread pool by setting the processModel in your web.config .
To my knowledge that information is not available to your application.
What is it you are trying to accomplish?
I have made an asp.net page which executes a long sp.
lets say the the function that executes the sp is called Func1.
Ive met with that problem :
If i ran Func1 in the same thread ( normal execution), the apppool won't recycle itself since he's seeing it as a busy/working.
But if I execute Func1 in another thread - so the apppool recycle's itself after the time that is set here :
My question is : why is that ?
is it true that if i run a command synchronously , so app is active and not eligible for apppool recycle ?
And if i create it in a new thread so it does eligible for apppool recycle ?
why is that ? Does the thread is less important then the main thread ?
ASP.NET maintains a list of thread pool threads that it is using to service requests. It knows it can recycle the app domain when none of its threads are active.
If you create a thread or use a thread pool thread without the knowledge of ASP.NET, it will not detect that your thread is active and may recycle.
When it recycles, it unloads the AppDomain which causes a ThreadAbortException to be thrown on your thread.
The normal solution to your requirements is to have a windows service that is controlled by the web app. This is obviously in a separate process and so is not affected by the web app recycling. However, this is a non-trivial exercise.
The quick-and-dirty solution is to asynchronously start a web request from within your web app. The page that starts the operation can then return. The "hidden" page that was called can block until the SP has completed. As I said, this is a nasty-but-easy solution.
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.