如何在MVC 4动作的漫长批处理过程中返回状态信息?

时间:2013-05-09 19:51:56

标签: asp.net-mvc asp.net-ajax batch-processing

在我的MVC 4应用程序中,我有一个视图,从客户端计算机上传文件:

<snip>
@using (Html.BeginForm("Batch", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <input class="full-width" type="file" name="BatchFile" id="BatchFile" 
    <input type="submit" value="Do It" />
}
<snip>

家庭控制器中的“批处理”操作会以一种非常冗长的方式处理该文件并对其进行处理....甚至分钟:

<snip>
[HttpPost]
public FileResult Batch(ModelType modelInstance)
{
    // Do the batch work.
    string result = LengthyBatchProcess(modelInstance.BatchFile.InputStream)
    var encoding = new ASCIIEncoding();
    Byte[] byteArray = encoding.GetBytes(result);
    Response.AddHeader("Content-Disposition", "attachment;filename=download.csv");
    return File(byteArray, "application/csv");
}
<snip>

这一切都运行正常,并且用户在批处理运行所花费的时间内被锁定并不是固有的问题。事实上,他们期待它。问题是用户可能无法知道此过程是花费几秒钟还是几分钟,我想在LongyBatchProcess运行时向他们提供状态信息。我研究了不显眼的ajax,但它似乎没有必要的功能,除非有一些方法可以链接不引人注目的ajax调用。有关如何最好地构建这个的任何想法?非常感谢提前。

2 个答案:

答案 0 :(得分:1)

您想要实现的目标需要一些工作。

一种方法是打开另一个频道(ajax调用)以获取进度报告。引自How do you measure the progress of a web service call?

  

在服务器上编写一个单独的方法,您可以通过传递已调度的作业的ID来查询该方法,该方法返回0到100(或0.0到1.0之间,或者其他)的近似值。

我在这件事上找到了a great tutorial

答案 1 :(得分:1)

是的,您可以开始以块的形式下载文件,以便用户可以看到浏览器的下载进度:

try
{
   // Do the batch work.
   string result = LengthyBatchProcess(modelInstance.BatchFile.InputStream)
   var encoding = new ASCIIEncoding();
   Byte[] byteArray = encoding.GetBytes(result);

   Response.Clear();
   Response.ClearContent();
   Response.Buffer = true;
   Response.AddHeader("Content-Disposition",
                      "attachment;filename=download.csv");
   Response.ContentType = "application/csv";
   Response.BufferOutput = false;

   for (int i = 0; i < byteArray.Length; i++)
   {
        if (i % 10000 == 0)
        {
             Response.Flush();
        }

   Response.Output.WriteLine(byteArray[i]);
   }
 }
 catch (Exception ex)
 {
 }
 finally
 {
   Response.Flush();
   Response.End();
 }