asp.net-mvc - 长时间运行的进程将返回一个文件

标签 asp.net-mvc

我正在使用 ASP.NET MVC 并且有一个长时间运行的进程。具体来说,我正在生成一个大 PDF 供用户下载。

我理解基本概念:

  1. 操作方法被调用
  2. 新线程开始生成进程
  3. 返回一个 View ,告诉用户正在生成 (pdf)
  4. 使用AJAX调用服务器并询问进度
  5. 完成后,将文件提供给用户下载。

我不完全理解的部分是:

  • 跨单独 AJAX 调用的线程管理。我可能需要某种方法来查找正在运行的线程并请求状态。是否有一个静态上下文可以保存对线程的引用?我知道 HttpContext.Application 中的数据缓存,这适合于此吗?
  • 以及如何呈现已完成的文件。我是否创建临时文件并提供下载链接?或者我可以进行最终的 AJAX 调用来返回文件吗?

最佳答案

它有效!

这是我所做的:

第 1 步和第 2 步 - 调用操作方法,启动长时间运行的线程

当我的操作方法被调用时,它会生成一个唯一的 ID。然后,我实例化 PdfGenerator 类的实例,创建一个调用 PdfGenerator.Generate 的新线程并启动它。

public class PdfGenerator
{
    public string State;
    public byte[] Data;

    public void Generate()
    {
        // Generate PDF/Long running process
        // Should update State as it goes
        // ...
        // Once finished, Data is populated with the binary byte[]
    }
}

线程启动后(或启动之前),生成器实例将存储在缓存中:

HttpContext.Cache[guid] = generator;

我还将 guid 附加到 ViewData,以便可以在我的 View 脚本中引用它。

第 3 步和第 4 步 - 显示和更新状态/进度 View

现在线程正在运行并且 PDF 生成已经开始,我可以显示我的进度 View 脚本。使用 jQuery 的 $.getJSON 我能够轮询一个单独的 Action 来查找生成的状态:

[OutputCache(Duration = 0, VaryByName = "none", NoStore = true)]
public JsonResult CheckPdfGenerationStatus(string guid)
{
    // Get the generator from cache
    var generator = HttpContext.Cache[guid] as PdfGenerator;

    if (generator == null)
        return Json(null);
    else
        return Json(generator.State);
}

我的 View 脚本解释 Json 并显示相应的进度信息。

第 5 步 - 向用户展示文件

一旦生成完成,生成器状态就会相应设置,当 jQuery 收到此信息时,它可以提供可用链接,或者使用 JavaScript location.href 直接发送文件。

设置并返回文件的 Action 方法只是将生成器从缓存中取出并返回附加的 byte[]

public ContentResult DownloadPdf(string guid)
{
    var generator = HttpContext.Cache[guid] as PdfGenerator;

    if (generator == null)
        return Content("Error");

    if (generator.State == "Completed")
    {
        return Content(generator.Data);
    }
    else
    {
        return Content("Not finished yet");
    }
}

我的实际工作有更详细的状态,例如已初始化、正在运行和已完成。以及进度百分比(以小数表示,1.0 表示完成)。

所以是的,希望这可以帮助其他尝试做类似事情的人。

关于asp.net-mvc - 长时间运行的进程将返回一个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1325054/

相关文章:

asp.net-mvc - 如何将 Display 属性的 ShortName 属性用于表头>

asp.net - ASP 5 MVC 6 - 优点和缺点 : multiple web api services - use one or more projects?

c# - 如何使输入字段可选?

c# - 为 SEO 友好的博客正确设置自定义路由

asp.net-mvc - 对 2 个字段进行 asp.net mvc 验证 - 如果输入其他字段,则必须存在一个

asp.net - 如何使TinyMVC .NET类库在ASP.NET MVC 2上运行?

jquery - 为整个 Visual Studio 解决方案安装旧版 NuGet 包

c# - Mvc,外键关系

asp.net-mvc - 用于 OpenID + OAuth + 普通身份验证的 ASP.NET MVC 解决方案

c# - asp.net mvc Bundle.IncludeDirectory 示例?