【问题标题】:MVC4 RDLC Stops all other requestsMVC4 RDLC 停止所有其他请求
【发布时间】:2015-05-23 11:49:30
【问题描述】:

我在 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;
    }

谢谢。

【问题讨论】:

  • 请贴出相关代码,并准确说明问题出在哪里。
  • @learner 我已经发布了代码,但代码没有什么特别之处。我只想知道 mvc rdlc 的默认行为。

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


【解决方案1】:

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

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

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

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

<sessionState mode="Off" />

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

【讨论】:

  • 我同意我应该创建一个单独的服务来完成报告生成工作。我们的数据库中有大量数据。如果用户想要一份报告,asp.net 会花一些时间使用 MVC 渲染报告来渲染 pdf 文件,并阻止所有其他请求,直到得到服务为止。再问一个问题,您认为仅使用异步操作就可以解决问题吗?还是单独的服务器生成报告仍然是最佳选择?
  • 不,异步操作不会解决任何问题。它们仅在您具有 I/O 绑定操作(例如网络调用)时才有用。
猜你喜欢
  • 1970-01-01
  • 2020-02-11
  • 2019-07-28
  • 2016-01-05
  • 1970-01-01
  • 2014-06-04
  • 2014-03-20
  • 2012-08-01
  • 2015-07-04
相关资源
最近更新 更多