ThreadPool.QueueUserWorkItem uses ASP.Net - c#

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.

Related

Delegate Function with IAsyncResult

I have been tasked to take over an old bit of code that uses delegates.
SearchDelegate[] dlgt = new SearchDelegate[numSearches];
IAsyncResult[] ar = new IAsyncResult[numSearches];
It then does a loop to start multiple delegate functions
for (int i = 0; i < numSearches; i++)
{
ar[i] = dlgt[i].BeginInvoke(....);
}
It then does a timed loop to get the results from the ar object.
It all seems to work fine. The issue I am having is that sometimes some of these delegate functions can take 3 to 4 seconds to start, even longer if the count goes above 10. Is this a common problem, or is there a setting I can tweak?
This is running on IIS. I can replicate the issue locally with the minimal machine resources being used.
Thanks all.
Daz
can take 3 to 4 seconds to start
is caused by the threadpool. When all threads are busy it only slowly (2/second) creates new threads.
You could up the min amount of threads in the pool but especially for a web app you should research, test and measure that extensively. ASP.NET also is a big stakeholder in the threadpool.
BeginInvoke method dispatches actual work to a thread pool, as it's written in this article. It may take some time actually, when there are no available idle threads. Thread pool may decide to wait for some work items completion or to add additional threads, accounting min and max limits.
Some additional info may be found here The managed threadpool and there Simple description of worker and IO threads in net and at remarks section of this article as well ThreadPool.SetMinThreads.
You should be aware that the same thread pool is used for HTTP requests processing, therefore it's usually senseless to offload custom non IO-bound work to the thread pool in web apps, as it won't give you any benefits and may even hurt performance due to additional thread switches. While BeginInvoke doesn't look as an invocation of asynchronous IO operation.
It doesn't actually matter which concrete thread executes the work — client still have to wait for the response the same amount of time. Looks, like you may, probably, win some time by performing work in parallel, but it won't be possible under load as far as there won't be available threads at thread pool for processing both HTTP requests and your custom work items.
You may want to check this thread for some additional details on this theme. It's related to Task, but this doesn't matter as far as both BeginInvoke and Task.Run are using the same thread pool under the hood.

Threads, Task, async/await, Threadpool

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.

Threads being taken from the Asp.net Thread pool?

When im running an Asp.net ( cs file) page :
and creating Thread T = new Thread(...) or using BeginInvoke()
Does the Thread is being taken from the Asp.net reserved Thread Pool ?
edit
Essentially, .NET maintains a pool of threads that can handle page
requests. When a new request is received, ASP.NET grabs one of the
available threads and uses it to process the entire page. That same
thread instantiates the page, runs your event handling code, and
returns the rendered HTML. If ASP.NET receives requests at a rapid
pace—faster than it can serve them—unhandled requests will build up in
a queue. If the queue fills up, ASP.NET is forced to reject additional
requests with 503 “Server Unavailable” errors.
I dont want to impact the Asp.net "requests threads..."
When you use new Thread(), it actually creates a new thread that is not related to the ThreadPool.
When you use Delegate.BeginInvoke(), the delegate executes on the .Net ThreadPool (there is no special ASP.NET ThreadPool).
Usually, it's best if you use the ThreadPool for a short running tasks and create a thread manually if you need to run a long-running task. Another option is to use .Net 4.0 Task, which gives you a nicer, consistent API. CPU-bound Tasks usually run on the ThreaPool, but you can specify a LongRunning option, so that they create their own thread.
In general, you probably don't have to worry about starving the ThreadPool, even in ASP.NET applications, because the limits are high enough (at least in .Net 4.0, they were somewhat lower in previous versions). If you do encounter these problems, you can try increasing the number of thread in the ThreadPool, or you can use a separate thread pool (which will require some code, but you should be able to find code for this on the internet). Using a custom thread pool is easier if you used Tasks, because it means just switching a TaskScheduler.

How to create threads in ASP.NET pages from CLR thread pool instead of ASP.NET pool?

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

Threadpool, order of execution and long running operations

I have a need to create multiple processing threads in a new application. Each thread has the possibility of being "long running". Can someone comment on the viability of the built in .net threadpool or some existing custom threadpool for use in my application?
Requirements :
Works well within a windows service. (queued work can be removed from the queue, currently running threads can be told to halt)
Ability to spin up multiple threads.
Work needs to be started in sequential order, but multiple threads can be processing in parallel.
Hung threads can be detected and killed.
EDIT:
Comments seem to be leading towards manual threading. Unfortunately I am held to 3.5 version of the framework. Threadpool was appealing because it would allow me to queue work up and threads created for me when resources were available. Is there a good 3.5 compatable pattern (producer/consumer perhaps) that would give me this aspect of threadpool without actually using the threadpool?
Your requirements essentially rule out the use of the .NET ThreadPool;
It generally should not be used for long-running threads, due to the danger of exhausting the pool.
It does work well in Windows services, though, and you can spin up multiple threads - limited automatically by the pool's limits.
You can not guarantee thread starting times with the thread pool; it may queue threads for execution when it has enough free ones, and it does not even guarantee they will be started in the sequence you submit them.
There are no easy ways to detect and kill running threads in the ThreadPool
So essentially, you will want to look outside the ThreadPool; I might recommend that perhaps you might need 'full' System.Threading.Thread instances just due to all of your requirements. As long as you handle concurrency issues (as you must with any threading mechanism), I don't find the Thread class to be all that difficult to manage myself, really.
Simple answer, but the Task class (Fx4) meets most of your requirements.
Cancellation is cooperative, ie your Task code has to check for it.
But detecting hung threads is difficult, that is a very high requirement anyway.
But I can also read your requirements as for a JobQueue, where the 'work' consists of mostly similar jobs. You could roll your own system that Consumes that queue and monitors execution on a few Threads.
I've done essentially the same thing with .Net 3.5 by creating my own thread manager:
Instantiate worker classes that know how long they've been running.
Create threads that run a worker method and add them to a Queue<Thread>.
A supervisor thread reads threads from the Queue and adds them to a Dictionary<int, Worker> as it launches them until it hits its maximum running threads. Add the thread as a property of the Worker instance.
As each worker finishes it invokes a callback method from the supervisor that passes back its ManagedThreadId.
The supervisor removes the thread from the Dictionary and launches another waiting thread.
Poll the Dictionary of running workers to see if any have timed out, or put timers in the workers that invoke a callback if they take too long.
Signal a long-running worker to quit, or abort its thread.
The supervisor invokes callbacks to your main thread to inform of progress, etc.

Categories

Resources