2010-12-01 217 views
15

在阅读ASP.NET MVC 2中的documentation on AsyncControllers之后,我想知道在这种情况下实现ajax进度栏的最佳方式是什么。这个教程似乎有点奇怪,根本不包括这个。使用ASP.NET MVC 2实现长时间运行任务的进度条AsyncController

我想实现一个AJAX进度条涉及需要额外的操作方法,返回当前任务的状态。但是,我不确定交换有关工作线程和该操作方法之间任务状态信息的最佳方式。

到目前为止,我的最佳想法是将信息与唯一ID一起放入会话字典中,并将该ID与客户端共享,以便查询状态。但也许有一种更容易的方式,我没有注意到。

这样做的最好方法是什么?

感谢,

阿德里安

+0

这就好比问你为什么没有获得正常请求的进度条。当你这么想的时候应该回答自己。 – nick 2011-01-20 22:58:45

+2

@nick:不是。普通请求不是长时间运行的。没有人需要进度条来处理最多花费几秒钟的时间。但是,如果您使用的是异步控制器,则预计该请求需要很长时间。那时你需要一个进度条。我是唯一一个认识到这一点的人吗? – 2011-01-21 16:27:53

回答

16

很有趣的问题!事实上,它似乎不是AsyncController的任务。异步控制器专为在服务器端长时间运行单个HTTP查询操作而设计。当您使用异步操作时,这只能帮助您在某些长时间运行的操作期间释放ASP.Net工作线程,并允许其在执行操作时处理其他请求。但从客户端的角度来看,这并不重要,这是否是异步控制器。对于客户端来说,这只是一个HTTP请求。

您需要在应用程序中使用一些长时间运行的查询服务重新设计此功能。下面是例子控制器,这样就能满足这样的工作流程:

public class LongOperationsController : Controller 
{ 
    public ActionResult StartOperation(OperationData data) 
    { 
     Guid operationId = Guid.NewGuid(); // unique identifier for your operation 
     OperationsService.DoStartOperation(operationId, data); // service starts to perform operation using separate thread 
     return new JsonResult(operationId); // operation id should be sent to client to allow progress monitoring 
    } 

    public ActionResult GetOperationStatus(Guid operationId) 
    { 
     var status = OperationsService.GetStatus(operationId); // this method returns some object, that describes status of operation (e.g. progress, current task etc.) 
     return new JsonResult(status); // returning it to client 
    } 

    public ActionResult GetOperationResult(Guid operationId) 
    { 
     var result = OperationsService.GetOperationResult(operationId); // this should throw exception if operation is not yet completed 
     return new JsonResult(result); 
    } 

    public ActionResult ClearOperation(Guid operationId) 
    { 
     OperationsService.ClearOperationResult(operationId); // we should delete operation result if it was handled by client 
     return true; 
    } 
} 

这里是客户端代码,这可能与该控制器进行交互:

var operationId; 
function startOperation(data) { 
    $.post('/LongOperations/StartOperation', data, function(response) { 
     operationId = response; // store operationId 
     startOperationMonitoring(); // start 
    }, 'json'); 
} 

function startOperationMonitoring() { 
    // todo : periodically call updateOperationStatus() to check status at server-side 
} 

function updateOperationStatus() { 
    // todo : get result of GetOperationStatus action from controller 
    // todo : if status is 'running', update progress bar with value from server, if 'completed' - stop operation monitoring and call finishOperation() 
} 

function finishOperation() { 
    // todo : get result of GetOperationResult action from controller and update UI 
    // todo : call ClearOperation action from controller to free resources 
} 

这是很基本的概念,也有一些在这里错过的物品,但我希望你会得到主要想法。例如:

  • 使用单独的OperationsService, 或不是;
  • 应该在哪里存储多长时间的运算结果(DB?Cache? Session?);
  • 是不是真的需要手动释放资源,做些什么时候 客户停止监视操作 (用户关闭浏览器)等

祝您好运!

相关问题