我正在使用ASP.NET MVC并且运行时间很长.具体来说,我正在生成一个大PDF供用户下载.
我理解基本概念:
我不完全理解的部分是:
HttpContext.Application,这适合这个吗?有用!
这就是我所做的:
步骤1和2 - 调用Action Method,启动长时间运行的线程
当我的action方法被调用时,它会生成一个唯一的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[]
}
}
Run Code Online (Sandbox Code Playgroud)
一旦线程启动(或在启动之前),生成器实例就存储在缓存中:
HttpContext.Cache[guid] = generator;
Run Code Online (Sandbox Code Playgroud)
我还将guid附加到ViewData,以便它可以在我的视图脚本中引用.
步骤3和4 - 显示和更新状态/进度视图
现在线程正在运行并且PDF生成已经开始,我可以显示我的进度视图脚本.使用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);
}
Run Code Online (Sandbox Code Playgroud)
我的视图脚本解释Json并显示适当的进度信息.
第5步 - 向用户显示文件
生成完成后,将相应地设置生成器状态,当jQuery收到此信息时,它可以提供链接,也可以使用javascripts直接发送文件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");
}
}
Run Code Online (Sandbox Code Playgroud)
我的实际工作我有更详细的状态,如Initialised,Running和Completed.以及进度百分比(以小数表示,1.0表示完整).
所以,是的,希望能帮助其他人尝试做类似的事情.
Cashe非常适合这种情况.只有一件事是确保在进程运行时永远不会删除缓存的项目(您可以使用ItemPriority.NotRemovable).
您可以将文件保存在临时文件夹中的磁盘上,也可以将其保留在缓存中一段时间(取决于).
我个人不喜欢用文件污染硬盘,所以我会将文件保存在缓存中(在几分钟内使用MediumPriority).但是文件很大并且可以生成经常考虑使用文件系统的数据库.
在客户端上,当最后一个Ajax请求返回结果时(看起来像{progress:"100%",resultUrl:" http://your.url/Where/ToGet/TheFile.aspx?file = GUID-OR-CACHE- KEY "})您可以将浏览器重定向到提供的网址.
反过来,它将该文件呈现为二进制结果.
客户端重定向可以使用以下Javascript完成:
location.href = response.resultUrl;
Run Code Online (Sandbox Code Playgroud)
顺便说一句,你如何生成PDF?NFOP?
| 归档时间: |
|
| 查看次数: |
2249 次 |
| 最近记录: |