How to cancel async task via web request? - c#

Here is the scenario: On user login I start a task which is listening to IMAP idle for mail notifications and it has live connection with the client via signalr(kind of push notification). Now the problem is how do i cancel this task? i.e. user cancel push notification or log out..
EDIT: as per my understanding for example if 5 users logged on to the site there are 5 tasks running? so how do i cancel individual tasks.

The asynchronous worker must be modified to support cancellation
http://www.csharp-examples.net/cancel-asynchronous-method/
You could also use the background worker which is a bit less complicated
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.cancelasync.aspx
A problem I have encountered when you send a cancel to an external source (DB, app) which has already started a job, if it does not support canceling, you may have to wait until it finishes.
EDIT: I've never done this with MVC but found a good article on 'Using a Cancellation Token' for an asycn process which takes a CancellationToken parameter in MVC4.
http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4
hope it helps.

Whenever you create a task you have to create a cancellation token and pass to it. Since each user is associated with a task you can store the task and cancellation token in the user's session.
Now using the cancellation token stored in the user's session you can easily cancel the task when he logs out or push the cancel button.
See this post for task cancellation.

The process can kill himself with no activity from the user.
The easiest way to exchange variables in the other thread - a file.
Suppose the client browser is still open, the javascript timer call Ajax requests, which writes on server the time stamp to a file. Your task also periodically reads the file, and when the timestamp is too old, the process kill himself. The value of the activity timeout you can set of your choice.

Related

How to keep a websites tasks alive after the website is closed

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.

Thread Sleep in c#

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).

Using Task with ASP.NET

I am trying to get some asynchronous work done with the System.Threading.Tasks.Task class. The scenario is simple. I have a web app and in one button click event I start a Task which must run to check some outside service for a couple of minutes. It is not a heavy task. All it's going to do is send a request every 5 seconds and get a response. But it must do it for at least a couple of minutes. So, I don't want user to wait until this task gets job done. After I have started the task, I immediately return to the user saying that the task started and he/she will be informed when it is done. I wonder if this task I created will cause any problems, since I returned and ended the HTTP response.
This type of "asynchronous work" isn't possible by using the Task type. As I mention on my blog, async does not change the HTTP protocol; you still get one response per request, that's it!
The ideal ASP.NET app does not do any work outside of a request/response pair. There are ways to make it work (also described on my blog), but it's almost never recommended.
The proper solution is to split up the processing. A web site (or service) should start the processing by placing a request into persistent storage (e.g., Azure queue), a separate worker service (e.g., Azure worker role / Win32 service) would do the polling and put the results into persistent storage (e.g., Azure table), and the web site/service could poll that.
You can consider using message based service bus, and a good tutorial on MSDN Building
Distributed Apps with NHibernate and Rhino Service Bus will be
very useful.
If you just return from a standard asp.net request then wouldn't you expect the HttpResponse to end? Starting up a task in itself won't hold the HttpResponse open, to that you'd need to stream your response and block on the server until your task is finished which is presumably not what you want to do?
Maybe you should look at some ajax on the client that periodically pings the server to see if the task has finished, or at HTML 5 push notifications if you know your browser is going to support it.
You can use this http://www.asp.net/web-forms/tutorials/aspnet-45/using-asynchronous-methods-in-aspnet-45 but imho ajax with web service much better

Background thread / process

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.

Run method asynchronously in asp.net

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).

Categories