ASP.NET MVC 4 Async Controller Callback

I just use the new Async Controller features in MVC 4 as described here http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4

If I have an action that can take 10-20 seconds, I would like to provide some status bar to notify the user about the progress. Async features have something to help?

EDIT: I will attack as I try to do this and see if there are any better ways.

public async Task<ActionResult> GizmosAsync() { return View("Gizmos", await GetGizmosAsync()); } private void GetGizmosAsync() { for(int i=0; i<10; i++) { lock(_locker) { _statusMessage = String.Format("{0} of 10", i); } DoSomethingLongRunning(); } } public ActionResult Status() { return Json(new { Status = _statusMessage }); } static readonly object _locker = new object(); static string _statusMessage = ""; .... <script> setTimeout(displayStatus, 1000); function displayStatus() { $.post("/controller/status", function(data) { alert(data.Status); }); } </script> 
+7
source share
2 answers

Asynchronous controllers are just a mechanism for freeing threads from ThreadPool in IIS in order to be able to process incoming requests during heavy load, but communication with the client remains like a regular request-request.

Status bars and sorting are usually just javascript, displaying something on the screen until the ajax request completes. I do not think MVC4 will be useful in this part.

You can do something like this: https://stackoverflow.com/a/4646262/2126 to display the "processing ..." <div> during ajax calls.

EDIT . If you need real progress and customer interaction (e.g. real progress), you should check SignalR http://www.hanselman.com/blog/AsynchronousScalableWebApplicationsWithRealtimePersistentLongrunningConnectionsWithSignalR.aspx And this related post: Async Controllers (MVC), long process with stops "

+15
source

This article describes what you want:

ASP.NET MVC 3: Async jQuery Progress Indicator for Long-Term Tasks

Controller:

 public class HomeController : Controller { private static IDictionary<Guid, int> tasks = new Dictionary<Guid, int>(); public ActionResult Index() { return View(); } public ActionResult Start() { var taskId = Guid.NewGuid(); tasks.Add(taskId, 0); Task.Factory.StartNew(() => { for (var i = 0; i <= 100; i++) { tasks[taskId] = i; // update task progress Thread.Sleep(50); // simulate long running operation } tasks.Remove(taskId); }); return Json(taskId); } public ActionResult Progress(Guid id) { return Json(tasks.Keys.Contains(id) ? tasks[id] : 100); } } 

View:

 <script type="text/javascript"> function updateMonitor(taskId, status) { $("#" + taskId).html("Task [" + taskId + "]: " + status); } $(function () { $("#start").click(function (e) { e.preventDefault(); $.post("Home/Start", {}, function (taskId) { // Init monitors $("#monitors").append($("<p id='" + taskId + "'/>")); updateMonitor(taskId, "Started"); // Periodically update monitors var intervalId = setInterval(function () { $.post("Home/Progress", { id: taskId }, function (progress) { if (progress >= 100) { updateMonitor(taskId, "Completed"); clearInterval(intervalId); } else { updateMonitor(taskId, progress + "%"); } }); }, 100); }); }); }); </script> <div id="monitors"></div> 
+5
source

All Articles