【问题标题】:How to return status information during lengthy batch process in MVC 4 action?如何在 MVC 4 操作中的冗长批处理过程中返回状态信息?
【发布时间】:2013-05-09 19:51:55
【问题描述】:

在我的 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>

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

【问题讨论】:

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


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 教程看起来很棒,我迫不及待想尝试一下。谢谢。
    【解决方案2】:

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

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

    【讨论】:

    • 这是个好主意,但我认为它不会像写的那样工作,因为它只会显示文件下载期间缓冲的输出进度。相反,必须在批处理过程本身期间写出响应,这可能是可行的,但在我的情况下需要对代码进行一些实质性的重构。但我很欣赏这个想法。谢谢。
    • 您说:'这一切都很好,并且在批处理运行所需的时间内用户被锁定并不是一个固有的问题。事实上,他们期待它。因此,请考虑重构是否值得付出努力。您可以将鼠标指针更改为“忙碌”或单击显示一些 gif 动画。大多数时候,当用户知道她正在做一个冗长的操作并为此显示一些指示时 - 他们很满意:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-02
    • 2021-07-27
    • 1970-01-01
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    相关资源
    最近更新 更多