Async Controllers (MVC), long running process with “stops”

后端 未结 3 1466
感情败类
感情败类 2021-01-14 03:06

I\'m interested in running a long process, I want to update the UI as soon as results start coming in and not wait for it to finish.

How would I go about this? I\'ve

相关标签:
3条回答
  • 2021-01-14 03:50

    You can run the long running task using ThreadPool.QueueUserWorkItem and it can update state in Application/Session which the user can poll. As you pointed that has some lifetime issues. Beyond what you pointed out, the app-pool could recycle - but maybe that's OK.

    What is the logical scope of that operation? Is it a system type long running task that someone/many folks need to query the progress on? Or is it a long running task on behalf of a specific user? If it's the latter, then it's OK if that user's session times out, etc... If it's the former then you need to be more durable. for example, you could store the task request, the state and the progress in a database. That way on app restart it can just pickup where it eft off and its easy to query by anyone (a noter decision point if system level task).

    The final consideration is whether you'll ever have more than one web roles (web farm/cluster). If that's ever a consideration than a DB or even separate worker role/service becomes more appropriate.

    So it all boils down to the type of task it is, who needs to monitor it and what are the durability requirements. If its just a user task, keep it simple, queueuserworkitem and session state.

    0 讨论(0)
  • 2021-01-14 03:51

    I was trying to solve something similar (reporting real-time progress from a long running server operation back to the client) recently and it turned out SignalR is a perfect fit for this situation.

    Basically it is a library wrapping long-polling and Web Sockets, using (transparently) whatever is available on server and client.

    I only have good experience with it so far.

    0 讨论(0)
  • 2021-01-14 03:52

    This article seems to describe what you want, simple and w/o SignalR:

    ASP.NET MVC 3: Async jQuery progress indicator for long running tasks

    Controller:

    public class HomeController : Controller { private static IDictionary tasks = new Dictionary();

     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);
       });
     });
    

    });

    0 讨论(0)
提交回复
热议问题