C# ASP.NET MVC 4 异步控制器回调

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11337770/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 17:29:53  来源:igfitidea点击:

ASP.NET MVC 4 Async Controller Callback

c#asp.netasp.net-mvc-4

提问by Craig

I am just using 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

我只是在 MVC 4 中使用新的异步控制器功能,如下所述http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4

If I have an action that may take 10-20 seconds to run I would like to provide some kind of status bar to notify the user of progress. Do the Async features have anything to help this out?

如果我的操作可能需要 10-20 秒才能运行,我想提供某种状态栏来通知用户进度。异步功能有什么可以帮助解决这个问题的吗?

EDIT: I will take a stab at how I will try and do it 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>

采纳答案by Pablo Romeo

Async controllers is just a mechanism for freeing threads from the ThreadPool in IIS in order to be able to handle incoming requests during heavy load, but the communication with the client remains as the usual request-response.

异步控制器只是一种从 IIS 中的 ThreadPool 中释放线程的机制,以便能够在高负载期间处理传入的请求,但与客户端的通信仍然是通常的请求-响应。

Status bars and the sort are usually just javascript displaying something on screen until the ajax request finishes. I don't think MVC4 will be of aid in that part.

状态栏和排序通常只是在 ajax 请求完成之前在屏幕上显示某些内容的 javascript。我不认为 MVC4 会在这部分有所帮助。

You could do something like this: https://stackoverflow.com/a/68503/1373170to display a "processing..." <div>during ajax calls.

您可以执行以下操作:https: //stackoverflow.com/a/68503/1373170<div>在 ajax 调用期间显示“正在处理...” 。

EDIT: If you need real client progress and interaction (such as real progress), you should check out SignalRhttp://www.hanselman.com/blog/AsynchronousScalableWebApplicationsWithRealtimePersistentLongrunningConnectionsWithSignalR.aspxAnd this related post: Async Controllers (MVC), long running process with "stops"

编辑:如果您需要真正的客户端进度和交互(例如实际进度),您应该查看SignalR http://www.hanselman.com/blog/AsynchronousScalableWebApplicationsWithRealtimePersistentLongrunningConnectionsWithSignalR.aspx以及这篇相关文章:Async Controllers (MVC), long running “停止”的过程

回答by Jeroen K

This article seems to describe what you want:

这篇文章似乎描述了你想要的:

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

ASP.NET MVC 3:用于长时间运行任务的异步 jQuery 进度指示器

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>