4

I've never tried running asynchronous tasks in mvc before so i'm not sure which direction go.

I have a class which generates an excel file from a lot of data which can take some time. I want it so when the user clicks a link they get a message saying "you'll be notified when complete" and the task starts, then they can carry on using the web app, and they get an on-screen notification once this is complete, preferably via ajax There could be a few tasks running at the same time. It would be good if i can see if the task is still running.

These tasks are never scheduled, always "on demand"

Which method is most suitable for this? I've seen there's system.threading, signalr, quartz.net, etc but some might be overkill.

thanks,

Sam

Sam Jones
  • 4,443
  • 2
  • 40
  • 45
  • 1
    Could the users navigate away from the page on which they started the task and yet get a confirmation on another page when the task has completed? Or will they be staying on the same page? The first could be pretty challenging to implement whereas an AJAX request could be all that it takes to do the second. – Darin Dimitrov Feb 10 '13 at 22:28
  • another page, if there's a way of checking if the task is complete in c# i could write a webservice to return a true or false on a timer using ajax – Sam Jones Feb 10 '13 at 22:33
  • I can think of 2 possibilities: standard AJAX polling at regular intervals and SignalR. – Darin Dimitrov Feb 10 '13 at 22:37
  • Thanks guys, i ended up using an [Asynchronous Controller](http://msdn.microsoft.com/en-us/library/ee728598(v=vs.100).aspx) containing [Task.Factory.StartNew()](http://msdn.microsoft.com/en-us/library/dd321439.aspx) and currently have an ajax call polling to check if the task is complete. It's not perfect so i will move to [SignalR](http://signalr.net/) once i've gotten it to work. – Sam Jones Feb 12 '13 at 11:04

2 Answers2

4

On the client side you will have to create javascript polling code.
Something like this:

(function poll(){
   setTimeout(function(){
      $.ajax({ url: "server/checkStatus", success: function(data){
        // check notification data and react accordingly
      }, dataType: "json"});
  }, 30000);
})();

See also:

On the server side create instance of object like this (simplified):

class MyTasks
{
   Dictionary<int, Task> tasks;

   public bool AllTasksDone {get;}
   public bool GetNumberOfRunnigTasksForUser(int userId){}

   public void AddTask(int userId, Task task){}
}

You can put this in Application or in Session (one instance per user session). And use it to answer poll requests.

Tasks can be created easily Task.StartNew(MethodName) or Task.StartNew(()=>{your code})

Just to mention - there is another way of doing this - WebSockets. But it's too heavy weapon. You probably don't want it.

Community
  • 1
  • 1
Anri
  • 6,175
  • 3
  • 37
  • 61
3

2 possibilities come to mind: AJAX or SignalR. The first is the naive approach. You start a task and then you would use AJAX call at regular intervals to check whether this task has finished. The drawback is that you will be sending lots of requests to your server.

The second approach involves using SignalR which in modern browsers could use WebSockets and Push notifications to the clients. Contrary to the AJAX polling technique, with SignalR it is the server that could inform the clients that some task has advanced or finished on the server. It is much more optimized for those kind of scenarios. Personally I would recommend you using SignalR for this task.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Thanks but i don't see how signalr allows me to start a background task while viewing other pages in the web app, how can i make it so the task runs after leaving the page? – Sam Jones Feb 10 '13 at 23:39
  • On each page you should have a script which subscribes to SignalR and when the task is completed the server will push a notification to all subscribed clients. – Darin Dimitrov Feb 11 '13 at 08:00
  • can we notify a specific user only? – R K Sharma Jun 29 '16 at 08:37