Cancelling long running tasks Asp.net - asp.net

I'm using ASP.NET WebForms.
In PostBack I create a Task(task is very long running).
In the html page I need a button that can cancel this task.
1. I click button GetResults that Run a task on the server
2. After some waiting I click button Cancel and I need the task will be cancelled
How can I do this?

Though, you can do it, it is generally not a good idea to create a long running task within ASP.NET, especially if they are background tasks.
Phil Haack has a great article on this - http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx/
Here is another good article on that topic - http://blog.stephencleary.com/2012/12/returning-early-from-aspnet-requests.html
You can consider things like message bus for this. You can also consider a simple TaskQueue table in the database to which your web application will insert a record corresponding to your task with status "Pending". Then you can have a background service (like windows service) that reads "Pending" tasks and marks them as "InProgress" during processing and "Complete" when its done. That way while the task is "Pending", you can have the user cancel the task from UI, which will simply delete the "Pending" record from the database.
Another option is to use a solution such as this - http://hangfire.io/

Related

Long Running task from asp.net web application (Only on user action)

I need to run a long running task like report export, report import feature which will take few minutes to hour to complete the task. I want to start the task as soon as user gives command from the asp.net mvc view.
I found various web portals, but I couldn't find the exact solution I was looking for or might be I didn't got their idea (or, limited by my experience). I don't need something that runs at certain time interval or at certain time-stamp of the day/week. I only need the background job to be executed on user request and update the task as completed in DB after it's done. So, the background job need to be always triggered by user only.
I assume the ideal solution will be something like, Background service/job is always in ready state to accept trigger from my web application in some kind of port and as soon as it receives command from web application, it (a) either send everything to job when requested for action (b) or, just poke job to start its task (based on the updated db table entry made just before the call action) . So, the user can browse through other pages in the application and can view the progress of all such tasks in one of the view (where he can even cancel or see the completed task). Note, that there can be simultaneous request for the job from different web users which should be treated as separate job (As data export differs based on user access-rights).
I want to go with the simple method, with 100% assurance of task to be done/not done as recorded in db (no crashing of service). What are the best approaches (except azure jobs) as i want to implement the service within same server and I have access to the server/virtual machine to install windows services/packages if needed.
Take look at this great article that Hanselman wrote:
How to run Background Tasks in ASP.NET
Also Hangfire is a mature library that can make development of application long running process more easy.
Hangfire is an open-source framework that helps you to create, process and manage your background jobs, i.e. operations you don't want to put in your request processing pipeline

ASP.NET feedback during long submit

This is probably a really simple thing. Basically, the user clicks a button and a potentially long running task happens. I'd like to do a few things like toggle the button's enabled state, show a spinner, etc. In VB.NET Winforms I'd just do Application.DoEvents() and the updates would happen and the code can continue. How can I do this in ASP.NET? (preferable serverside or minimal javascript)
There are a few ways to approach this in ASP.Net depending on exactly what your requirement is. Getting the process started is fairly easy, but monitoring it for completion from the client side will require more work in both the server and the client.
The basic outline of the solution is:
1) Perform some action on the client that initiates the action. For example, you could post the entire page back on a button click, initiate an ajax request, or have a partial page postback depending on how much information you need from the page.
2) On the server side, initiate the task using a BackgroundWorker, make an entry in a workflow queue, or store a request in a database table that is monitored by a service that is responsible for performing the action.
3) Back on the client side, use javascript start a window.timeout loop that, when it times out, issues an ajax request to the web server to check on the completion. Using a timeout loop like this will ensure that the UI remains responsive and that any animations being displayed will display correctly. How you check on the completion will depend on how your server-side implementation is designed, but will almost certainly require a database.
We use the following general approach for initiating reports from the web client, which can be long running:
When the user initiates the report, open a new window to the report generation page on the client using javascript, passing the page enough parameters to get it started. Opening a separate window allows the user to continue working, but still see that there is something happening.
The user interface for the report page basically contains an animated GIF so that the user knows that something is going on.
When the report page is initially loaded on the server, it generates a unique id for monitoring the status of the report and embeds this in javascript for use in monitoring the status. It then stores this unique identifier in a database table that contains the unique id and a status column, initializing the status to requested.
Once the database entry has been made, the page fires off a BackgroundWorker to initiate the action and then returns the page to the user.
When the page is displayed, javascript starts a window.timeout loop that periodically fires off an ajax request to the web server, which then checks the database for the status of the report using the unique identifier created earlier.
When the backgroundworker finishes the report, either successfully or in failure, it updates the database table with the status, location of the report or error messages and terminates.
When the javascript loop finds that the report generation has completed, it either displays the error message or the report to the user.
Hopefully, this gives you some ideas for solving your issue.
The issue with this could be that once the page is posting you can't update other sections of the page.
you can use multiple asp:updatepanel and communicate to other update panel's causing the state to change in the panel.
take a look at this link:
http://www.ajaxtutorials.com/ajax-tutorials/tutorials-using-multiple-updatepanels-in-net-3-5-and-vb/
it will show you how to accomplish this.

How to do background processing in ASP without using windows service

Scenario
I have an web application which needs some calculations and processing on data. This job is a long running job(few hours). Job is initiated by user.
Requirement.
User Clicks on Process Data.
Some functions are called to start data processing.
Data Processing runs for hours.
User is given feedback of percentage completed etc.
Even if user logs off and then again log on he should get this feedback.
The requirement is somewhat similar to Spiceworks. Where it runs in background to detect the devices/computers in network and the user is notified in his page about the progress. But spicework uses windows service. We don't want to us windows service.
Now the question is.
What if user closes the page, will the task still run in background.
This task has to be completed fully.If terminated in between output will not have any meaning.
How to actually to design this long running process. In ASP.Net environment.
Also is there a way to show all/same user who logs in the status of processing.
There are multiple ways to schedule a job in the background. You can use SQL Job, Windows Service or Scheduled Tasks.
I would design it like this:
From my ASP.NET page - I will store an indication in the database for the job to start which will then be picked by the scheduled task. This task is nothing but a console application which pulls data from the database to see which tasks user initiated and then take the next action in there.. For the percetage complete you can store those values from your job into DB and your page will access the dB to show it to user anytime they come to the page.
Here is another thread where long running tasks in IIS are discussed:
Can I use threads to carry out long-running jobs on IIS?

A Way to Run a Long Process From ASP.NET page

What are your most successful ways of running a long process, like 2 hours, in asp.net and return information to the client on the progress.
I've heard creating a windows service, httphandler and remoting can be successful.
Just a suggestion...
If you have logic that you are tyring to utilize already in asp.net... You could make an external app (windows service, console app, etc.) that calls a web service on your asp.net page.
For example, I had a similiar problem where the code I needed was asp.net and I needed to update about 3000 clients using this code. It started timing out, so I exposed the code through a web service. Then, instead of trying to run the whole 3000 clients at through asp.net all at once, I used a console app that is run by a nightly sql server job that ran the web service once for each client. This way all the time consuming processing was handled by the console app that doesn't have the time out issue, but the code we had already wrote in asp.net did not have to be recreated. In the end slighty modifying the design of my existing architecture allowed me easily get around this problem.
It really depends on the environment and constraints you have to deal with...Hope this helps.
There are two ways that I have handled this. First, you can simply run the process and let the client time out. This has two drawbacks: the UI isn't in synch and you are tying up an IIS thread for non-html purposes (I did this for a process that used to return quickly enough but that grew beyond time-out limits).
The better way to handle this is to write a "Service" application that handles the request as passed through a database table (put the details of the request there). Then you can create a window that gives the user a "window" into ongoing progress on the task (e.g. how many records have been processed or emails sent). This status window can either have a link to permit the user to refresh or you can automate the refresh using Ajax callbacks on a timer.
This isn't directly applicable but I wrote code that will let you run processes similar to "scheduled tasks" inside of ASP.NET without needing to use windows services or any type of cron jobs.
Scheduled Tasks in ASP.NET!
I very much prefer WCF service to scheduled tasks. You might (off the top of my head) pass an addr to the WCF service as a sort of 'callback' that the service can call with progress reports as it works.
I'd shy away from scheduled tasks... too course grained.

BackgroundWorker From ASP.Net Application

We have an ASP.Net application that provides administrators to work with and perform operations on large sets of records. For example, we have a "Polish Data" task that an administrator can perform to clean up data for a record (e.g. reformat phone numbers, social security numbers, etc.) When performed on a small number of records, the task completes relatively quickly. However, when a user performs the task on a larger set of records, the task may take several minutes or longer to complete. So, we want to implement these kinds of tasks using some kind of asynchronous pattern. For example, we want to be able to launch the task, and then use AJAX polling to provide a progress bar and status information.
I have been looking into using the BackgroundWorker class, but I have read some things online that make me pause. I would love to get some additional advice on this.
For example, I understand that the BackgroundWorker will actually use the thread pool from the current application. In my case, the application is an ASP.Net web site. I have read that this can be a problem because when the application recycles, the background workers will be terminated. Some of the jobs I mentioned above may take 3 minutes, but others may take a few hours.
Also, we may have several hundred administrators all performing similar operations during the day. Will the ASP.Net application thread pool be able to handle all of these background jobs efficiently while still performing it's normal request processing?
So, I am trying to determine if using the BackgroundWorker class and approach is right for our needs. Should I be looking at an alternative approach?
Thanks and sorry for such a long post!
Kevin
In your case it actually sounds like the solution you will be looking for is multifaceted (and not a simple in and done project).
Since you said that some processes can last for hours that is absolutely not something for ASP.NET to own. This should be ran inside a windows service and managed with native windows threading.
You will need to implement some type of work queue in your service and a way to communicate with the queue. One way is to expose a WCF service for all actions your service will govern. Another would be to have service poll a database table and pick up work from the table.
To be able express the status of the process you will want the ASP.NET application to be able to have some reference to the processID for example the WCF service returns a guid identifier. Then you have a method that when you give it the processID it will return the status of the process. You can then implement the polling of that service call using AJAX and display any type of modal you wish.
Another thing to remember is that you need to design your processes to have knowledge of where it is and where it will be when it is finished so it can track the state it's in. For example, BatchJobA is run and will have 1000 records to process. The service needs to know what record it's on or what the current % of competition is for it to be able to return information to the UI. For sql queries that take a very long time to execute this can be very problematic to accurately gauge where it is unless you do alot of pre and post processing of temp tables that you can in the middle of it read the status of the temp tables to understand where it is.
Based on what you are saying I think that BackgroundWorker is not a good choice.
Furthermore keeping this functionality as a part of your main app can be problematic, specifically because you do not want the submitted processing to be interrupted if the main app recycles. You can play with asynch processing but it still will be a part of the main app AppDomain - all of it will die if the app recycles.
I would suggest buidling a separate app implementing this functionality. In a similar situation I separated background processing to a Windows service and hosted a web service in it as a means of communication
You might consider a slightly different approach.
For example, have a command and control table in which you send commands like "REFORMAT PHONE NUMBERS" or whatever.
Then have a windows service monitoring that table. Whenever a record shows up, run the command.
This eliminates any sort of worry about a background thread. Further you have a bit more flexibility with regards to what's in the queue, order of operations including priority, etc. Finally, you would have a definitive list of what is running or needs to run.
As an option, instead of a windows service you might just use a SQL job to execute every so often to watch your control table and perform the requested action.

Resources