Considerations for ASP.NET application with long running synchronous requests - asp.net

Under windows server 2008 64bit, IIS 7.0 and .NET 4.0 if an ASP.NET application (using ASP.NET thread pool, synchronous request processing) is long running (> 30 minutes). Web application has no page and main purpose is reading huge files ( > 1 GB) in chunks (~5 MB) and transfer them to the clients. Code:
while (reading)
{
Response.OutputStream.Write(buffer, 0, buffer.Length);
Response.Flush();
}
Single producer - single consumer pattern implemented so for each request there are two threads. I don't use task library here but please let me know if it has advantage over traditional thread creation in this scenario. HTTP Handler (.ashx) is used instead of a (.aspx) page. Under stress test CPU utilization is not a problem but with a single worker process, after 210 concurrent clients, new connections encounter time-out. This is solved by web gardening since I don't use session state. I'm not sure if there's any big issue I've missed but please let me know what other considerations should be taken in your opinion ?
for example maybe IIS closes long running TCP connections due to a "connection timeout" since normal ASP.NET pages are processed in less than 5 minutes, so I should increase the value.
I appreciate your Ideas.

Personally, I would be looking at a different mechanism for this type of processing. HTTP Requests/Web Applications are NOT designed for this type of thing, and stability is going to be VERY hard, you have a number of risks that could cause you major issues as you are working with this type of model.
I would move that processing off to a backend process, so that you are OUTSIDE of the asp.net runtime, that way you have more control over start/shutdown, etc.

First, Never. NEVER. NEVER! do any processing that takes more than a few seconds in a thread pool thread. There are a limited number of them, and they're used by the system for many things. This is asking for trouble.
Second, while the handler is a good idea, you're a little vague on what you mean by "generate on the fly" Do you mean you are encrypting a file on the fly and this encryption can take 30 minutes? Or do you mean you're pulling data from a database and assembling a file? Or that the download takes 30 minutes to download?
Edit:
As I said, don't use a thread pool for anything long running. Create your own thread, or if you're using .NET 4 use a Task and specify it as long running.

Long running processes should not be implemented this way. Pass this off to a service that you set up.
IF you do want to have a page hang for a client, consider interfacing from AJAX to something that does not block on IO threads - like node.js.
Push notifications to many clients is not something ASP.NET can handle due to thread usage, hence my node.js. If your load is low, you have other options.

Use Web-Gardening for more stability of your application.
Turn-off caching since you don't have aspx pages
It's hard to advise more without performance analysis. You the VS built-in and find the bottlenecks.

The Web 1.0 way of dealing with long running processes is to spawn them off on the server and return immediately. Have the spawned off service update a database with progress and pages on the site can query for progress.
The most common usage of this technique is getting a package delivery. You can't hold the HTTP connection open until my package shows up, so it just gives you a way to query for progress. The background process deals with orchestrating all of the steps it takes for getting the item, wrapping it up, getting it onto a UPS truck, etc. All along the way, each step is recorded in the database. Conceptually, it's the same.
Edit based on Question Edit: Just return a result page immediately, and generate the binary on the server in a spawned thread or process. Use Ajax to check to see if the file is ready and when it is, provide a link to it.

Related

ASP.NET Web app with large amount of threads, most efficient method

I have a web app that allows you to paste a large number of urls in (anywhere from 2000 - 15000), it then visits each page to download the source and do some processing.
I've tried a couple methods, currently it uses ajax to send each url one at a time to a WebMethod which then uses ThreadPool.QueueUserWorkItem to push the request onto a queue and do the processing when it can so that many threads are running at the same time. This seems to cause problem (the Visual Studio web server dies occasionally which can't be good).
Just wondering if anyones done anything similar, knows a better way. I guess being able to throttle the number of concurrent threads somehow would help.
Thanks
Don't use the built in webserver. Use IIS proper
Along with using IIS as mentioned above, you might benefit from using asynchronous web requests. (See How to use HttpWebRequest (.NET) asynchronously? for more info.)
This will prevent the amount of blocking done on each thread, which should reduce the number of threads needed if your processing isn't too heavy.

asp.net infinite loop - can this be done?

This question is about limits imposed to me by ASP.NET (like script timeout etc').
I have a service running under ASP.NET and I want to create a counterpart service for monitoring.
The main service's data is located at a database.
I was thinking about having the monitor service query the database in intervals of 1 second, within a loop, issued by an http request done by the remote client.
Now the actual serving of this monitoring will be done by a client http request, which will make the script loop (written in C#) and when new data is detected it'll aggregate that data into that one looping request output buffer, send it, and exit the loop, thus finishing the request.
The client will have to issue a new request in order to keep getting updates.
This is actually exactly like TCP (precisely like Windows IOCP); You request the service for data and wait for it. When it arrives you fire another request.
My actual question is: Have you done it before? How did it go? Am I limited by some (configurable) limits imposed by the IIS/ASP.NET framework? What are my limits in such situation, or, what are better options without complicating things too much?
Note that I do not expect many such monitoring requests at a time, maybe a few dozens.
This means however that 10 such concurrent monitoring requests will keep 10 threads busy, and the question is; Can it hurt IIS/performance? How will IIS handle 10 busy threads? Will it issue more? What are the limits? This is just one example of a limit I can think of.
I think you main concern in this situation would be timeouts, which are pretty much configurable. But I think that it is a wrong solution - you'd be better of with some background service, running constantly/periodically, and writing the monitoring data to some data store and then your monitoring page would just return it upon request.
if you want your page to display something only if the monitorign data is available- implement it with ajax - on page load query monitoring service, then if some monitoring events are available- render them, if not- sleep and query again.
IMO this would be a much better solution than a reallu long running requests.
I think it won't be a very good idea to monitor a service using ASP.NET due to the following reasons...
What happens when your application pool crashes?
What if you decide to do IISReset? Which application will come up first... the main app, or the monitoring app?
What if the monitoring application hangs due to load?
What if the load is already high on the Main Service. Wouldn't monitoring it every 1 sec, increase the load on the Primary Service, as well as IIS?
You get the idea...

Does an ASP.net page running on IIS make use of multicore processors?

I've got an ASP.net page that runs a script which takes anywhere between 1 second and 10 minutes to run dependant on the parameters passed in to it.
My question is, if the server is multicore, will this script automatically make use of all the processors, or is it constricted to one.
Thanks for any help
No, the page will only run on one core.
IIS uses several threads to process requests, but it only uses one thread at a time for each request.
If you want the code to make use of more than one core, you have to start threads yourself.
I believe each request only gets assigned one processor/thread by default. You can optimize it yourself by making multiple threads in your code to do your work (that way you might be using more processors).
You can mark your application pool to have more threads, however this will not assign more threads/processors to a single request, but will allow you to handle more requests at once (because the requests are balanced over the threads).
ASP.NET is multi-threaded.
So a new thread is used to handle each page request.
It all depends on the workload of a given processor if the new thread is assigned to a different CPU/Core.
But all of your cores are used by ASP.NET. So your app is never restricted to one CPU.
But the real question is: what is your goal?
1] Are you just afraid that your long running operations will hang ASP.NET?
2] Or do you wish to reduce the time it takes for your script to execute?
If you make your long-running-page asynchronous, then each thread will be
returned immediately to the ASP.NET thread pool, which drastically increases
the performance of your site. This solves problem 1.
Read up on the parallel task library extensions to see how you can more effectively use all cores to handle long running tasks. Most tasks can be divided into sub tasks which
can run in parallel. This solves problem 2.
Hope this helps.

Does parallel work in an ASP.NET work process block connection threads?

i'm not sure I've used the correct terms in the title but this is my question.
If i have a stock standard ASP.NET webpage (webforms or mvc) and i wish to do some longish processing, I create a new process and fire that off.
Eg. save an uploaded file to a local folder then do some image manipulation on it
Eg. save an uploaded video to a local folder then do some video encoding on it.
So while this process is doing it's thing, will it effectively block on available connection hitting the IIS server, to be processed/handled?
Like, I heard there was a finite number of connections that can get processed at once ... which is the number of threads on the ... err thread-queue? Hmm.
Basically, can i have some background tasks going ahead and it doesn't impact the number of possible requests i can process.
If you spawn a new thread, you CAN continue processing the response to the user, and the connection will close and release the connection to the pool. We use this type of setup for error logging purposes where I work. The user gets a quick error message and we have a lengthy process that tries to figure out what happened and inform us through various mechanisms.
But don't take my word for it, spawn a thread with a long sleep and test it out for yourself.
You can have a look at Use Threads and Build Asynchronous Handlers in Your Server-Side Web Code and Asynchronous Pages in ASP.NET 2.0.

Multithreading in asp.net

What kind of multi-threading issues do you have to be careful for in asp.net?
It's risky to spawn threads from the code-behind of an ASP.NET page, because the worker process will get recycled occasionally and your thread will die.
If you need to kick off long-running processes as a result of user actions on web pages, your best bet is to drop a message off in MSMQ and have a separate background service monitoring the queue. The service could take as long as it wants to accomplish the task, and the web page would be finished with its work almost immediately. You could accomplish the same thing with an asynch call to a web method, but don't rely on getting the response when the web method is finished working. From code-behind, it needs to be a quick fire-and-forget.
One thing to watch out for at things that expire (I think httpContext does), if you are using it for operations that are "fire and forget" remember that all of a sudden if the asp.net cleanup code runs before your operation is done, you won't be able to access certain information.
If this is for a web service, you should definitely consider thread pooling. Too many threads will bring your application to a grinding halt because they will eventually start competing for CPU time.
Is this for file or network IO? If so, you should also consider using asynchronous IO. It can be a bit more of a pain to program, but you don't have to worry about spawning off too many threads at once.
Programmatic Caching is one area which immediately comes to my mind. It is a great feature which needs to be used carefully. Since it is shared across requests, you have to put locks around it before updating it.
Another place I would check is any code accessing filesystem like writing to log files. If one request has a read-write lock on a file, other concurrent requests will error out if not handled properly.
Isn't there a Limit of 25 Total Threads in the IIS Configuration? At least in IIS 6 i believe. If you exceed that limit, interesting things (read: loooooooong response times) may happen.
Depending on what you need, as far as multi threading is concerned, have you thought of spawning requests from the client. It's safe to spawn requests using AJAX, and then act on the results in a callback. Or use a service as a backgrounding mechanism, which runs every X minutes and processes in the background that way.

Resources