MVC4 RDLC停止所有其他请求

时间:2015-05-23 11:49:31

标签: c# multithreading asp.net-mvc-4 rdlc

我在MVC4 Web应用程序中实现了RDLC报告(返回pdf文件字节)。每当用户请求报告时,除非呈现此报告,否则Web应用程序将停止对所有用户的所有其他请求。有些报告在100页左右非常大,因此Web服务器生成和呈现该报告需要一段时间。在此期间,Web服务器不会处理任何其他请求。假设Web服务器忙于呈现报告,并且在新选项卡中我尝试请求一些其他数据,除非RDLC完成其操作,否则它将不会显示。在开发机器中也是如此。请有人建议这是我的网络应用程序中的设计缺陷还是这是默认行为?

我有办法用多线程或多任务解决这个问题吗?

这是报告呈现代码,以防您希望查看。但我只想让其他人分享他们的经历。

public byte[] RenderReport(PageType pageType, string ReportFormat, string ReportPath, ReportDataSource[] ReportDataModelList, out string mimeType, ReportParameter[] ReportParameters)
    {
        LocalReport lr = new LocalReport();

        string path = Path.Combine(ReportPath);
        lr.ReportPath = path;

        foreach (ReportDataSource rds in ReportDataModelList)
        {
            lr.DataSources.Add(rds);
        }

        lr.EnableExternalImages = true;
        lr.SetParameters(new ReportParameter("PrintedBy", PrintedBy));

        foreach (ReportParameter rp in ReportParameters)
            lr.SetParameters(rp);

        string encoding;
        string fileNameExtension;
        string pageWidthHeight;

        if (pageType == PageType.Portrait)
            pageWidthHeight =
                "  <PageWidth>8.5in</PageWidth>" +
                "  <PageHeight>11in</PageHeight>";
        else if (pageType == PageType.Landscape)
            pageWidthHeight =
                "  <PageWidth>11in</PageWidth>" +
                "  <PageHeight>8.5in</PageHeight>";
        else
            pageWidthHeight =
                "  <PageWidth>8.5in</PageWidth>" +
                "  <PageHeight>11in</PageHeight>";

        string deviceInfo =
            "<DeviceInfo>" +
            "  <OutputFormat>" + ReportFormat + "</OutputFormat>" +
            pageWidthHeight +
            "  <MarginTop>0.3in</MarginTop>" +
            "  <MarginLeft>0.3in</MarginLeft>" +
            "  <MarginRight>0.3in</MarginRight>" +
            "  <MarginBottom>0.3in</MarginBottom>" +
            "</DeviceInfo>";

        Warning[] warnings;
        string[] streams;
        byte[] renderedBytes;

        renderedBytes = lr.Render(
            ReportFormat,
            deviceInfo,
            out mimeType,
            out encoding,
            out fileNameExtension,
            out streams,
            out warnings);

        return renderedBytes;
    }

感谢。

1 个答案:

答案 0 :(得分:2)

我怀疑您所观察到的问题与ASP.NET sessions(我想您正在使用)的以下事实有关:

  

对于每个会话,访问ASP.NET会话状态是独占的,这意味着   如果两个不同的用户发出并发请求,则访问每个用户   同时授予单独的会话。但是,如果两个并发   请求是针对同一会话进行的(使用相同的SessionID)   value),第一个请求获得对会话的独占访问权   信息。第二个请求仅在第一个请求之后执行   完了。 [...]

由于浏览器选中了ASP.NET会话,因此您基本上是在尝试从同一会话发出并发请求。

您可以简单地从应用程序中禁用会话状态,您将看到可以发出并发请求:

<sessionState mode="Off" />

显然,这只是观察行为的原因。在所有情况下,您应该避免在ASP.NET应用程序中长时间运行操作。这些操作阻止了工作线程,从而限制了应用程序的服务容量。理想情况下,应该从ASP.NET应用程序中卸载那些长时间运行的操作。例如,您可以拥有一个负责生成这些报告的Windows服务,而ASP.NET应用程序只会安排生成报告,而服务将执行实际工作。