Before I go into this question, I d like to say that, I have read the threading modeling for IIS 7, 7, 7.5 so I know how threads are handled.
My application starts a thread when a request comes in.
We can assume the threads as cron jobs.
GET request comes in, Lets say /Handle
in the scope of /Handle I start a thread from that action , THREAD A
I am not long polling the GET request, so it returns back to the
user right away. So thread handling the GET is returned to the POOL
Then I wait until the thread A completes to do anything else.
So No threads are running as far as I know. Both the thread that was
handling the GET and THREAD A has exited.
I make the same request a few times SEQUANTIALLY. I always wait for both threads to exit.
After a while `Thread.Start()1 function blocks.
Questions :
I know that the threads are returning and I am not leaking any ghost threads.
Why does IIS not allowing me to start new threads after a like 4-5 requests. ?
What is the right way to create application thread for the user application.
If I said Thread t= new Thread(), does this allocate a thread from the pool that handled the GETS or CLR?
I am using IIS7.
I know that I exit each thread, I call a JOIN on THREAD A , and it never blocks, and at this point I am not worried about scalability so I always have ONE user hitting the server sequentially.
So to answer your question "What is the right way to create application thread for the user application?" (i.e. ASP.NET application) - You have many options:
run on the ASP.NET thread, without any threading - ASP.NET will still handle more then one request
use async calls (see async operations) for long running operations
use CLR ThreadPool
send a message to some other server (e.g. using WCF services), so the long running processing takes place outside the Web server.
You mentioned reading about threading in ASP.NET, but in "MSDN: Performing Asynchronous Work, or Tasks, in ASP.NET Applications" there's a relatively short description of how threading in ASP.NET works. At the end of the post, there's a question:
"Q4: Should I create my own threads (new Thread)?" and the answer for that question is "A4) Please don’t (create new Threads). Or to put it a different way, no!!! (...) ".
And to answer your question: "Why does IIS not allowing me to start new threads after a like 4-5 requests"?
That's really a strange behaviour, maybe IIS knows that your are doing it wrong ;)
Related
I am getting really confused here about multithreading :(
I am reading about the C# Async/Await keywords. I often read, that by using this async feature, the code gets executed "non-blocking". People put code examples in two categories "IO-Bound" and "CPU-bound" - and that I should not use a thread when I execute io-bound things, because that thread will just wait ..
I dont get it... If I do not want a user have to wait for an operation, I have to execute that operation on another thread, right ?
If I use the Threadpool, an instance of "Thread"-class, delegate.BeginInvoke or the TPL -- every asynchronous execution is done on another thread. (with or without a callback)
What you are missing is that not every asynchronous operation is done on another thread. Waiting on an IO operation or a web service call does not require the creation of a thread. On Windows this is done by using the OS I/O Completion Ports.
What happens when you call something like Stream.ReadAsync is that the OS will issue a read command to the disk and then return to the caller. Once the disk completes the read the notifies the OS kernel which will then trigger a call back to your processes. So there is no need to create a new threadpool thread that will just sit and block.
What is meant is this:
Suppose you query some data from a database (on another server) - you will send a request and just wait for the answer. Instead of having a thread block and wait for the return it's better to register an callback that get's called when the data comes back - this is (more or less) what async/await does.
It will free the thread to do other things (give it back to the pool) but once your data come back asynchronously it will get another thread and continue your code at the point you left (it's really some kind of state-machine that handles that).
If your calculation is really CPU intensive (let's say you are calculating prime-numbers) things are different - you are not waiting for some external IO, you are doing heavy work on the CPU - here it's a better idea to use a thread so that your UI will not block.
I dont get it... If I do not want a user have to wait for an operation, I have to execute that operation on another thread, right ?
Not exactly. An operation will take however long it is going to take. When you have a single-user application, running long-running things on a separate thread lets the user interface remain responsive. At the very least this allows the UI to have something like a "Cancel" button that can take user input and cancel processing on the other thread. For some single-user applications, it makes sense to allow the user to keep doing other things while a long-running task completes (for example let them work on one file while another file is uploading or downloading).
For web applications, you do not want to block a thread from the thread pool during lengthy(ish) IO, for example while reading from a database or calling another web service. This is because there are only a limited number of threads available in the thread pool, and if they are all in use, the web server will not be able to accept additional HTTP requests.
I'm developing a system which works like following structure
Level1-sub-tasks are created by task via TaskFactory of .net 4.0, and Level2-sub-tasks are created by level1-sub-tasks similarly.
All tasks work file in debug, but when I deploy that on IIS server, all level2 sub tasks stops executing.
I'm not an experienced developer of iis, does it has any limitation for multi-level thread(task)?
If you do spawn new threads while handling a request, make sure they have all finished before returning a response. You may think "I'm gonna return to the user asap, and leave a thread in the background saving stuff to the database." This is dangerous, mainly because the AppDomain may be recycled, aborting your background threads.
Alternatively, use the IRegisteredObject interface to tell asp.net you're doing some work in the background. The approach is detailed here: http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx/
Do note that this is not fail-proof though, and that there are better approaches to this - it all depends on what you're trying to achieve. In most cases (e.g., sending out email notifications), the best solution is to schedule a task (in a separate process) that dequeues work items periodically.
In Asp.Net for creating a huge pdf report iam using "ThreadPool.QueueUserWorkItem", My requirement is report has to be created asynchronously , and i do not want to wait for the Response. I plan to achieve it through below code
protected void Button1_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(report => CreateReport());
}
public void CreateReport()
{
//This method will take 30 seconds to finish it work
}
My question is ThreadPool.QueueUserWorkItem will create a new thread from Asp.Net worker process or some system thread. Is this a good approach ?, I may have 100 of concurrent users accessing the web page.
The QueueUserWorkItem() method utilizes the process's ThreadPool which automatically manages a number of worker-threads. These threads are assigned a task, run them to completion, then are returned to the ThreadPool for reuse.
Since this is hosted in ASP.NET the ThreadPool will belong to the ASP.NET process.
The ThreadPool is a very good candidate for this type of work; as the alternative of spinning up a dedicated thread is relatively expensive. However, you should consider the following limitations of the ThreadPool as well:
The ThreadPool is used by other aspects of .NET, and provides a limited number of threads. If you overuse it there is the possibility your tasks will be blocked waiting for others to complete. This is especially a concern in terms of scalability--however it shouldn't dissuade you from using the ThreadPool unless you have reason to believe it will be a bottleneck.
The ThreadPool tasks must be carefully managed to ensure they are returned for reuse. Unhandled exceptions or returns from a background thread will essentially "leak" that thread and prevent it from being reused. In these scenarios the ThreadPool may effectively lose it's threads and cause a serious slowdown or halt of the process.
The tasks you assign to the ThreadPool should be short-lived. If your processing is intensive then it's a better idea to provide it with a dedicated thread.
All these topics relate to the simple concept that the ThreadPool is intended for small tasks, and for it's threads to provide a cost-saving to the consuming code by being reused. Your scenario sounds like a reasonable case for using the ThreadPool--however you will want to carefully code around it, and ensure you run realistic load-tests to determine if it is the best approach.
The thread pool will manage the number of active threads as needed. Once a thread is done with a task it continues on the next queued task. Using the thread pool is normally a good way to handle background processing.
When running in an ASP.NET application there are a couple of things to be aware of:
ASP.NET applications can be recycled for various reasons. When this happens all queued work items are lost.
There is no simple way to signal back to the client web browser that the operation completed.
A better approach in your case might be to have a WCF service with a REST/JSON binding that is called by AJAX code on the client web page for doing the heavy work. This would give you the possibility to report process and results back to the user.
In addition to what Anders Abel has already laid out, which I agree with entirely, you should consider that ASP.NET also uses the thread pool to respond to requests, so if you have long running work like this using up a thread pool thread, it is technically stealing from the resources which ASP.NET is able to use to fulfill other requests anyway.
If you were to ask me how best to architect it I would say you dispatch the work to a WCF service using one way messaging over the MSMQ transport. That way it is fast to dispatch, resilient to failure and processing of the requests on the WCF side can be more tightly controlled because the messages will just sit on the queue waiting to be processed. So if your server can only create 10 PDFs at a time you would just set the maxConcurrentCalls for the WCF service to 10 and it will only pull a maximum of 10 messages off the queue at once. Also, if your service shuts down, when it starts up it will just begin processing again.
I've a long running task in my asp.net web application and hence I run that task in a new thread and constantly poll to check the status of the thread (by using a ticker control which ticks every 5 seconds and postbacks to the server and checks the status of the thread). I used the Session State to share the variables between the thread and the page. But I learned that it is a bad practice to access the session from a background thread. What is the best method to share variables between a thread and the asp.net page which created that thread?
I don't inherently see an issue with using Session - it's basically a thread-safe dictionary. You probably need to ensure that your background thread locks SyncRoot; the Page class does this automatically.
There are, of course, other options as well - static variables (but then you get into AppDomain issues), or out-of-band mechanisms (which is what Session is) like a DB or messaging service. Unless you have some other need for those technologies, though, Session is probably the simplest.
Couple of caveats I can think of:
If the Session expires, what happens when writing to it from the background thread? Exception? Keeps it alive?
How do you detect that the background thread has exited abnormally? Store the thread in Session?
What happens to Session if there's an unhandled exception on the background thread?
It is not a direct answer to your question, rather a suggestion to use a separate WCF service for the long running jobs. Your web server gets really busy working on a long task, which I assume use lots of CPU.
Anticipated problems
The overall performance of web server will drop
You will not be able to scale such solution
Alternatively, consider putting the long running logic into a WCF service. You can start and check the job status by issuing simple AJAX query with the ID of the job. Each job can be started in a separate thread and the result/status persisted into a queriable storage.
If I create a new thread on an ASP.NET page the IsThreadPoolThread property is true.
First question is, is it from ASP.NET pool or CLR pool ?
Second question is, if it is from ASP.NET pool then how to create a thread from CLR and don't use ASP.NET pool ?
I need a synchronous solution for long-running requests (full story).
First off, there is no difference between the ASP.NET thread pool and the CLR thread pool. ASP.NET processes pages on the CLR thread pool, so your ASP.NET pages will always have IsThreadPoolThread == true.
I'm curious as to how you are creating your thread. Are you using the System.Threading.Thread constructor, or are you using ThreadPool.QueueUserWorkItem? If you are using ThreadPool.QueueUserWorkItem, then the threads that you are getting are coming from the regular .net thread pool.
Finally, as I have posted before, it is always a bad idea to attempt long running tasks from within ASP.NET. My general suggestion is to use a background windows service to process these requests, since ASP.NET may terminate your background thread at any point. More details here, if you must do it in IIS: http://csharpfeeds.com/post/5415/Dont_use_the_ThreadPool_in_ASP.NET.aspx
While there is a point to be made about minimizing impact on transactions and catering for the unforeseen in distributed transactions, in this example its really not necessary to reinvent IIS just because the process is long running. The whole "IIS can die at any moment" meme is IMHO greatly exaggerated.
Yes, you can manually restart IIS or app pool but so can you restart any other service which does the same job for the same effect. As for auto-recycle IIS uses overlapping worker processes and will never terminate a started thread forcefully (unless time out occurs). If that were the case we would have serious problems with any hosted application (what's to stop IIS from killing a fast response thread 0.001ms after start)
In essence, let the IIS do what IIS does best and don't insist on sync operation, you'll just waste pool's thread waiting for blocking I/O which is what I believe you are trying to avoid. You already made a good choice by going to Asynchronous Handlers (ASHX), use IHttpAsyncHandler implementation to spawn your custom thread which will then block to your heart's desire without affecting the web application and its pool. Once you initiate an async operation thread the asp.net thread will go back to its own pool and will be ready to start serving a new request. With a default limit of 100 threads in a pool and given that your process is low-on-cpu-high-on-bandwidth I doub't you'll ever run out of pool threads before you run out of pipe space :). For more information on how to build async handler check this link (its an old article but valid non the less):
Use Threads and Build Asynchronous Handlers in Your Server-Side Web Code
There is in fact a difference in threads in ASP .NET: Worker threads and IO threads (system threads which i believe you state as CLR thread).
Now ASP .NET use a worker thread on each request, unless custom configurations are used, and these worker threads are limited on your CPU number; this configuration can be set in IIS.
When you start an asynchronous task inside ASP.NET by using delegate for instance, you are using another worker thread. Delegates are a quick and dirty way of starting something asynchronous in .NET :)
If you want to start a new thread which does NOT use up a worker thread, then you must explicitly start a new thread like: new Thread()....etc. Now this comes with alot code management, and does not follow the event based asynchronous pattern.
However there is one way you can start asynchronous threads safely and that is by using .NETs own asynch methods on objects. Things you normally would use asynch for like SQL commands, webservice calls, etc. All these have a BEGIN and an END method.
By using these methods you will never use a worker thread, but an IO thread.
ASP .NET has a few tricks up its sleeve when it comes to asynchronous pages.
There are two alternatives:
Asynchronous page: which lets your page cycle to be asyncronous. This basicly means that the page is requested asynchronous.
Asynchronous page tasks: which lets you define tasks that will fire asynchronous when the page starts. Its kinda like Asynch threads, just that ASP .NET does alot of things for you, and its more restricted.
I dont have all the details, but please look into the two options on MSDN Library.
Here is an article on the subject: asynch programmin