2015-05-23 53 views
0

我在MVC4 web应用程序中实现了RDLC报告(返回pdf文件字节)。无论用户何时请求报告,Web应用程序都会停止对所有用户的所有其他请求,除非此报告已呈现。有些报告大约100页左右,所以Web服务器需要一段时间才能生成并呈现报告。在此期间,Web服务器无法处理其他请求。假设Web服务器正忙于渲染报告,并且在一个新选项卡中尝试请求一些其他数据,除非该RDLC完成其操作,否则它将不会显示。在开发机器中也是如此。请有人建议这是我的Web应用程序中的设计缺陷还是这是默认行为?MVC4 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; 
    } 

谢谢。

+0

请张贴相关的代码,并确切地显示问题出在哪里。 –

+0

@learner我已经发布了代码,但没有什么特别的代码。我只想知道mvc rdlc的默认行为。 –

回答

2

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

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

而且由于浏览器选项卡ASP.NET会话,您基本上试图从同一个会话发出并发请求。

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

<sessionState mode="Off" /> 

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

+0

我同意我应该创建一个独立的服务来完成报告生成工作。我们的数据库中有大量数据。并且如果用户想要报告,则asp.net需要一段时间才能使用MVC呈现报告呈现PDF文件,并阻止所有其他请求,直到提交为止。还有一个问题,你认为单独的异步行动就能解决问题吗?或单独的服务器进行报告生成仍然是最佳选择? –

+1

不,异步操作不会解决任何问题。它们仅在您有I/O绑定操作(如网络呼叫)时才有用。 –