views:

1136

answers:

4

I am thinking on the following approach but not sure if its the best way out:

step1 (server side): A TaskMangaer class creates a new thread and start a task.
step2 (server side): Store taskManager object reference into the cache for future reference.
step3 (client side): Use periodic Ajax call to check the status of the task.

Basically the intention is to have a framework to run a background task (5mins approx) and provide regular feedback on the web UI for the percentage of task completed.

Is there a neat way around this or any existing asp.net API that will be helpful ?

Edit 1#: I want to run the task in-proc with the app.

Edit 2#: Looks like badge implementation on stack overflow is also using the cache to track background task. http://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/

+1  A: 

Microsoft Message Queuing was built for scenarios like the one you try to solve: http://www.microsoft.com/windowsserver2003/technologies/msmq/default.mspx Windows Communicatio Foundation also has message queuing support. Hope this helps.

Thomas

Thats a valid option. We do not want to scale to msmq at this point. Just looking for - ad hoc background task using the best effort approach within the bound of asp.net process.
dotnetcoder
+1  A: 

One approach for doing this is to use application state. When you spawn a worker thread, pass it a request ID that you generate, and return this to the client. The client will then pass that request ID back to the server in its AJAX calls. The server will then fetch the status using the request ID from application state. (The worker thread would be updating the application state based on its status).

Yuliy
+1  A: 

I think the problem with storing the result in the cache is that ASP.NET might scavenge that cache entry for other purposes (ie if its short on memory, if its grumpy, etc). Something that is served from the cache should be something you can recreate on demand if its not found in the cache, the ASP.NET runtime is free to dump cache entries whenever it feels like it.

The usage of the cache in the badge discussion seems fundamentally different, in that case the task was shortlived. The cache was just being used as a hacky timer to fire off the task periodically.

Can you confirm this is a task that is going to take 5 minutes, and require its own thread that whole time? This is a performance concern in itself, you will only be able to support a limited number of such requests if each requires its own thread for so long. Only if thats acceptable would I let the task camp a thread for so long.

If its ok for these tasks to camp a thread, then I'd just go ahead and store the result in a dictionary global to the process. The key of the dictionary would correlate to the client request / AJAX callback series. The key should incorporate the user ID as well if security is at all important.

If you need to scale up to many users, then I think you need to break the task down into asynchronous steps, and in that case I'd probably use a DB table to store the results (again keyed per request / user).

Frank Schwieterman
Frank - Yes the task is approximately less than equal to 5 mins max. Its a good idea to use a static dictionary ( hashtable is thread safe ) instead of the cache.I am looking at 3 to 4 parallel tasks at a given time.
dotnetcoder
Sounds like you're ready then. I'm curious how you'll correlate the status requests with a task, but thats not too hard. Another question is how to scavenge the hashtable (given the client may DC and not be able to tell you when they no longer care about status updates). A timer should work.
Frank Schwieterman
dotnetcoder
And I am using a UserID+GUID as the key in dictionary - to uniquely identify a task at application level.
dotnetcoder
A: 

I saw an approach to a similar problem somewhere. The solution was something like:

  1. Start the background task on server.Return immediately with a url to the result.
  2. Until the result is posted, this url will return 404.
  3. The client checks periodically for this url.
  4. The client reads the results when they are finally posted.

The url will be something like http://mysite/myresults/cffc6c30-d1c2-11dd-ad8b-0800200c9a66. The best document format is probably JSON.

If feedback on progress is important, modify the document to also contain status (inprogress/finish) and progress (42 %).

Thomas Eyde