I am writing an application for the web, but, the problem is a task may take a long time to complete (minutes or hours). During this time I assume the website will time out or similar.
Let's assume the user can click the Start button and various processes are carried out. My question is about keeping the process (the task) alive, even if they leave the website, without configuring IIS (if possible).
Simply, if I spin off a new thread to perform a long winded background task, is that background task still owned by the application (the website) and if I close the application (the website) will it automatically be aborted or will it continue?
I guess the better way would be for the code behind to start up a process on the server (a different application) but, I'm more keen on understanding how the thread works.
To do that, start that Thread using Ajax. It would be sent asynchronously to the server and server can work on it until it completes the task.
Once you send the request to server browser doesn't need to be active. Server has to do the work and Browser is needed only to show the result of the request. Once the user would send the request, its not required for him to stay there. He can leave, and the server would continue the work.
User can navigate away from the Website and don't have to stay in the website for the process to complete. It would then depend on the System to complete the task.
Related
I use quartz in my asp website, i initialize the scheduler in application_start method and shutdown in application_end method ,my trigger will fire everyday but I found that my scheduler will automatically shutdown if there are not request for a while ,so my background works will not triggered,are there any better way to keep the scheduler life long and only shutdown when the server stopped?
For better knowledge sharing:
There are two suggestions:
http://www.codeproject.com/Articles/12117/Simulate-a-Windows-Service-using-ASP-NET-to-run-sc
http://weblog.west-wind.com/posts/2007/May/10/Forcing-an-ASPNET-Application-to-stay-alive
In general, if you need reliable scheduling, you should not do it within a web site.
As you've found, the worker process will be shut down after a period of time. Even if you force the worker process to run all the time, there are conditions that may cause it to terminate as well. It's just not a good idea.
Instead, you should write a Windows Service and run quartz.net in that.
If you cannot install services (say you're in a shared hosting environment), then your options are more limited.
There is an IIS configuration that allows worker processes to stay on all the time. I found this setting through another SO answer link.
Edit C:\Windows\System32\inetsrv\config\applicationHost.config to include:
<applicationPools>
<add name="MyAppWorkerProcess" managedRuntimeVersion="v4.0" startMode="AlwaysRunning" />
</applicationPools>
Scott Guthrie (Microsoft Product Manager for .NET) has answerered a question directly related to the OP's question (link).
#Dominic Pettifer,
If I set startMode="AlwaysRunning" does this mean the web app will
'never' shut down and will always be kept running, even with no
traffic hitting the site for a long period (unless of course it's
manually shut down, or server is switched off/crashes etc.)? The
reason I ask is because I like to run background threads/services on
the IIS ASPNET worker process instead of using Windows Services (we
deal with clients with lots of security restrictions on their servers
which makes running a Windows Service difficalt or impossible).
Normally I have to devise something that hits the website periodically
to keep the ASPNET worker process alive and stop it from shutting
down.
This should mean that the application and worker process is always
running - so I think that does indeed handle your scenario well for
you.
Hope this helps,
Scott
I wondered the same thing. Ultimately, whilst I agree with the general consensus, I wanted to see how it could be done, because I've been in a similar situation myself, where Windows Services were not available to me.
All I did was create a new job which, when executed sends a HTTP request to the application itself. For me, I pointed it at a page which simply contained #Datetime.Now.ToString().
The action of sending a HTTP request to itself should be enough to keep the scheduler (and parent worker process) alive.
It does not however stop the application from being stopped/recycled without warning. If you wanted a way to handle that, then you'd likely need more than one site running which pings both itself and the other site. This way, if one site goes down, the other can hit it (assuming it's started) to bring it back.
A much simpler way to is use a quality assurance checker. Using the tool Zapix I was able to schedule my website to be quality checked every 20 minutes. Zapix simply visited the site and received and http response. By using Zapix, it mimicked the functionality of manually visiting the website to trigger the emails. That way, the Application Pool threads are constantly woke.
Ok. I'm calling an external script [Edit: web service] that's doing an asynchronous task. It usually takes one to two minutes to complete.
In the meantime i want to display to the user the "please wait" message, since i need to make another call to check if the previous task has been completed yet before i continue.
Using timers is not exactly a good solution. I need the user to actually wait before i continue.
So the question i have is whether or not thread.sleep will put the entire web application to sleep or just the one for the current UI?
I don't want the UI for other website visitors to hang.
I'm not sure how this works in the production environment.
I use iis 7 on windows 2008 r2
Thanks
Thread.Sleep will only affect the current thread - but it's not what you want to do anyway.
You should return a complete response from your web application - but one which starts a Javascript timer to fire in a few seconds, and then make an AJAX call back to your web app to check whether the task has completed. (You should include some sort of "task ID" in your response so that the server knows which task to check.)
If you just sleep before returning the response, your user won't see any message until the sleeping has completed.
More info would be nice. However:
I guess you are going to make a website (asp.net mvc or webforms) since you are using iis7. Just run the server and let the client use a Ajax call to ask status of the task. The task when finished should be stored somewhere, preferably a database. You can also use xml or whatever to have a point where you can then save the taskid and or it is completed or not. And just let the ajax do a call every 5 sec until it returned at the taskid true on completed.
You shouldn't use Thread.Sleep. Assuming this is a web application...
One request should start the task and return a job token.
With another request, the user should be able to check the status of that job (by passing the token).
When the job is complete, the user should be able to get the result of the job (by passing the token).
I have a application that will allow a user to upload a file. After the upload is complete there are a number of processing steps that must be done on the server (decompression, storage, validation, etc ...) thus the user will be informed sometime later by email when everything is complete.
I have seen a number of examples where the BackGroundWorker from System.ComponentModel is used to allow asynchronous work to be done in another thread. However, it seems like they lead to the user eventually getting a response. In our case no web response is necessary - the code can take up to 30 minutes to complete.
Is there another way to start a completely separate thread/process that will keep running even after the user completely closes their session?
If there is no need to respond immediately, you want to offload to some other process to do the heavy lifting. I would dump it in a DB, folder or post to a Message Queue. The worker processes (Windows Services?) would process the files, reading from the db, file system or queue. When the work is done, your worker process can call out to your ASP app (webhook style) if it needs to know when it's done. Just a suggestion.
Write a Windows Service that will run on the ASP.NET server. Architect it in such a way that it can accept and queue job requests. The queue will allow you to create the optimal number of threads in a ThreadPool for executing a subset of the queued jobs concurrently. Submit jobs to the Windows Service using either .NET Remoting, or WCF.
If processing can take up to 30 minutes, I'd recommend skipping using a background thread from the the web worker process and using something like a Windows service instead, or running a console application on a schedule using the Windows scheduler.
Once the file is uploaded, you would add it to a queue of some sort (either in a database, or using a message queuing system like RabbitMQ if you're feeling adventurous). Your web request could then return immediately and let the user know that the file is being processed, and the background service would pick the item up off the queue and continue the processing, emailing the user when it is complete.
I have a webpage with a button that generates some files to a server path. (It takes somewhere from 5 to 20 minutes). I want to create an async task that will continue executing even after the user closes the browser. Is it possible to do this with asp.net 4 and C#?
You do not control the thread pool in an asp.net application. You cannot even guarantee that a request will be completed on the same thread that it started with. Creating threads uses the same application pool that the web server uses, and you can use up all the request threads leaving your web server unavailable to process requests.
You should implement a windows service that hosts a WCF service that you can call from within your web application. In the service you can then fire off a thread to process the long running process. At the end of that process you can then update a status flag (e.g from Processing to Complete) that the user can view to determine if the files are done processing.
I would recommend using Topshelf to implement your windows service, it will save you much headache.
Actually, it is recommended that you not do this. Instead, the recommended way is to create a service (e.g. a windows service) that performs your processing asynchronously. In your web application, you create methods that starts the process, and another method that polls the service to determine if processing has completed.
There are a number of reasons for this, but one of the biggest is that the default and recommended configuration for webservers allows the server to kill long-running requests.
Or that I didn't understand what you want to do, or that you don't need to do a thing.
After the request was sent, the request process continues no matter if the user browser was closed or not. You don't need to do a thing
Fabulous nature of stateless WEB applications...
Creating new thread / using thread pool is the easiest approach to create run away tasks.
Note that there is no guarantees that process will stay alive for duration of a long task - so be prepared to handle partial completion and manual restarts. I.e. AppPoll recycle due to config change.
Easiest way is to put your task on the ThreadPool. The thread pool threads will stay alive even after the web page has completed rendering. The code would look like the following:
/* Beginning Method */
object someData = new object();
ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessAsync), someData);
/* Ending Method */
static void ProcessAsync(Object stateInfo)
{
string dataToString = stateInfo.ToString();
}
you have to create a thread that does the long running task
have a look at the below:
http://kiranpatils.wordpress.com/2010/01/01/performing-a-long-running-task-with-asp-net/
Anyway what ever you start on the server it will continue running even if the user close the browser(until you recycle the app-pool or restart the web server).
In an asp.net web form, I keep getting a connection reset error message. The page is doing a some long running processing (about 2-5 minutes).
I have no problem when the web request comes from the same machine as the web server. But when the request originates across the network, I get a connection reset error about 1:30 or 2 minutes into waiting for a response.
I have set the in web.config for this application and put the application it's own application pool.
What else can I try?
Edit
The purpose of this page is to accept input from the user, calculate something, and send the result back to them. The long running calculation isn't something I can offload until a later time.
A common way to handle this is to kick of a background thread to process your data, but immediately return an identifier to the browser, normally as a link. When the link is clicked, the server checks to see if processing is complete - if it is, show the results, if not, display a "please wait" message and the link again, or auto-refresh the page...
Do not make the browser wait for this long. Make the request asynchronous, make it return right away. If you need to make user wait - do it using Javascript