为啥我的 PDF 生成进程会锁定我站点中的其他 ajax 进程?

Posted

技术标签:

【中文标题】为啥我的 PDF 生成进程会锁定我站点中的其他 ajax 进程?【英文标题】:Why does my PDF generation process lock other ajax process in my site?为什么我的 PDF 生成进程会锁定我站点中的其他 ajax 进程? 【发布时间】:2013-10-10 11:32:45 【问题描述】:

我有一个需要定期生成大型报告的 MVC3 应用程序。用户可以选择他们的标准并启动报告。现在我正在使用 javascript window.open() 方法打开一个新选项卡/窗口。在生成报告时,用户无法使用该站点。一切都等到生成报告。 生成报告的代码是:

private FileStreamResult doSpecReport(List<int> idProjItems)

    PdfDocument outputDocument = new PdfDocument(); // returning to the user
    foreach(var id in idProjItems)
    
        var item = _entities.ProjectEquipmentItems.First(f => f.idProjectEquipmentItem == id);
        var cutsheetPath = item.CutSheet;
        Dictionary<string, string> dictionary = new Dictionary<string, string>();
        dictionary.Add("p_idEquipmentItem", id.ToString());
        var fs = GetReporthtml("NameOfReport", dictionary); // Returns FileStreamResult from crystal

        var inputDocument1 = CompatiblePdfReader.Open(fs.FileStream); // add report to output doc
        int count = inputDocument1.PageCount;
        for(int idx = 0; idx < count; idx++) 
        
            PdfPage page = inputDocument1.Pages[idx];
            outputDocument.AddPage(page);
        

        if (!string.IsNullOrEmpty(cutsheetPath))
        
            cutsheetPath = Path.Combine(Server.MapPath("~/Files/CutSheetFiles/"), cutsheetPath);
            if (File.Exists(cutsheetPath))
            
                var inputDocument2 = CompatiblePdfReader.Open(cutsheetPath);//, PdfDocumentOpenMode.Import);
                count = inputDocument2.PageCount;
                for(int idx = 0; idx < count; idx++)
                
                    PdfPage page = inputDocument2.Pages[idx];
                    outputDocument.AddPage(page);
                
            
        
    

    var ms = new MemoryStream();
    outputDocument.Save(ms, false);
    ms.Position = 0;

    return new FileStreamResult(ms, "application/pdf")
    
        FileDownloadName = "Report.pdf"
    ;

我不确定我是否做错了什么,我不明白为什么这个过程会占用浏览器的所有资源。感谢您的帮助。

更新:调用 doSpecReport 的代码版本。围绕成功的代码不起作用。

$.ajax(
    url: url,
    data: qdata,
    type: "POST",
    success: function (result)  // this doesn't actually work.
        var obj = $('<object type="application/pdf"   border="2"></object>');
        obj.attr('data', 'data:application/pdf;base64,' + result);
        $(".mask").hide();
        $('#divContainer').append(obj);
    
);

【问题讨论】:

这看起来像 C# 代码,而不是 JavaScript;最终用户系统上的浏览器除了等待服务器返回之外什么都不做……如果您希望浏览器在服务器处理时保持响应,则需要使用某种异步调用。 .. 你是对的,javascript标签是由于我打开调用此代码的窗口的方式。我在想可能有一些方法可以修改该代码,以确保该代码在不同的线程中运行。并且通过 ajax 发送请求仍然持有网站的人质。 您能否发布您尝试用于异步调用的实际 JavaScript 代码? 编辑了我的问题以添加代码。 【参考方案1】:

您必须在服务器端生成一个临时文件位置并返回位置 url。您不能使用二进制 PDF 设置 HTML 文档内容。您能否生成报告并将其存储在临时位置并在响应中传递其 url 链接。假设 doSpecReport 生成一个名为 mypdf.pdf 的临时 pdf 文件,

然后在你的成功块中,你可以将它添加到对象数据属性中,使最终对象看起来像this

  <object   type="application/pdf" data="/my_pdf.pdf?#zoom=85&scrollbar=0&toolbar=0&navpanes=0" id="pdf_content">

  </object>

【讨论】:

我真正的问题是,即使我这样做了,而且我已经这样做了,网站在整个过程完成之前不会响应。我想在另一个窗口中生成报告,然后能够在该网站工作时使用该网站。我不想将文件写入磁盘。我们将在 IIS 中实现一个指向报表服务器样式项目的新站点。 只是为了澄清 - 当您说您的网站没有响应时。我假设,您被锁定在 JavaScript 端而不是服务器端。正确的?您甚至在客户端遇到过成功障碍吗?如果您想在另一个窗口中生成报告 - 为什么要做 $.ajaxPost?为什么不使用 window.open() 和服务器知道如何服务的随机 url。 我对完成工作并返回 pdf 的 url 做了一个 window.open。虽然这个窗口正在运行并且没有返回我的 pdf,但我的网站被锁定,这意味着如果我想移动到不同的页面,我不能。如果我对启动 ajaxPost 的页面执行 window.open,则会出现同样的问题。 您使用的是 ASP .net 开发服务器吗?此服务器 cannot process more than one request at a time. 。我想这就是原因,你什么都做不了。 好的@smash51,感谢您的耐心等待。它变得有趣了。 :) 你能做几件事吗?我认为您的 IIS Express 没有处理多个请求。你在使用ASP.NET session states。我有一种感觉,它的服务器。有没有其他方法可以确认服务器是否正在并行处理多个请求。

以上是关于为啥我的 PDF 生成进程会锁定我站点中的其他 ajax 进程?的主要内容,如果未能解决你的问题,请参考以下文章

为啥文档中的超链接会导致找不到页面

为啥我的 ASP.NET MVC 站点中的此 AJAX 请求会触发预检检查?

站点关闭时防止打开文件锁定

M1 mac 进程不断自动生成并锁定我的端口

为啥我创建 PDF 文档时没有应用我的字体?

为啥我的 Service Fabric 代码会锁定自己的 PDB?