【茶包射手日記】Reporting Service 報表改 RDLC 或升級 .NET 4.0 後嚴重變慢
0 |
同事分享的案例,也算是古蹟維護相關問題。
原本於 ASP.NET 2.0 網站運行多年的 RDLC 報表,在專案升級 ASP.NET 4.0 後有水土不服症狀:
- 較複雜報表顯示時 CPU 飆高,吃掉整顆 CPU (同時預覽兩張報表甚至 CPU 100%)
- 經交叉比對,記憶體使用量明顯較 ASP.NET 2.0 高
- 報表產生速度嚴重變慢,ASP.NET 2.0 時代顯示報表只需幾秒,升到 ASP.NET 4.0 後要等 30 秒,有時還一片空白
MSDN 論壇有篇類似案例討論,情境為 Report Server 伺服器端報表改 RDLC, 使用 Fields!MyFieldName.Value 分群的報表正常,使用 Fields("MyFieldName").Value 動態欄位分群的報表速度慢八倍,且動態參數用愈多愈慢。即使資料筆數不多,用到一個動態參數 18 秒,用 4 個動態參數報表產生時間便超過一分鐘。
有位遭遇類似的網友,提供了寶貴解答,連絡微軟開發團隊協助檢視,得到的結論為:
關鍵在於 .NET 4.0 改變了 RDLC 的運作模式,Report Viewer 預設會將 Expression Evaluation 移到 Sandbox Domain 執行(參考:Expression Evaluation in Local Mode),好處是減少 Memory Leak 風險,代價則是會產生 Sandbox Domain 與應用程式 AppDomain 間的跨 Domain 溝通,形成效能瓶頸。這個效能問題與 .NET CAS 權限管控有關,有一些解決方法:
- 避用動態表達示(如 Fields("MyFieldName").Value)或改用 .NET 3.5 (且不要啟用 ExecuteReportInSandboxAppDomain), 讓報表在應用程式的 AppDomain 執行可避開上述問題,但會提高 Memory Leak 風險且無法使用 .NET 4 功能。
- 在 web.config 加入
<trust legacyCasModel="true" level="Full"/>
啟用舊版 CAS 模型,減緩因 CAS 管控產生的效能衝擊。 (可能有其他副作用,但這是 MS Team 提供的 Workaround 之一)
除了上述解法,我心中更好的做法是調整 RDLC 報表,把複雜的分群、彙整邏輯拉到 C# 端處理做出半成品,RDLC 只留簡單的呈現邏輯(註:子報表也很雷,要小心),相同邏輯用 C# 寫比用 RDLC 實現簡單,而且效能好 N 倍。MDSN 論壇討論中有類似建議 ( to replace the parts of the report definition that result in the extremely poor performance at runtime...including use of parameters in the grouping expression... ) ,這與同事在簡化報表可明顯提升速度的經驗吻合,符合三人成虎的門檻(咦?),在處理 RDLC 效能不佳問題時,可優先納入考量。
A case of extremely poor performance of RDLC report after upgraded to .NET 4.0.
Comments
Be the first to post a comment