2015-05-23 119 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綁定操作(如網絡呼叫)時纔有用。 –