【问题标题】:Wpf crystal report memory leakage issuewpf水晶报告内存泄漏问题
【发布时间】:2018-11-15 05:42:58
【问题描述】:

我在 wpf 中遇到水晶报表的问题,虽然一段时间后水晶报表查看器会在我们的应用程序中不断打开报表,但水晶报表查看器会再次停止加载水晶报表并抛出以下异常:

加载报告失败。 不支持的操作。 JRC 引擎处理的文档无法在 C++ 堆栈中打开。

异常详情是:

CrystalDecisions.ReportAppServer.ReportClientDocumentWrapper.EnsureDocumentIsOpened() 在 CrystalDecisions.CrystalReports.Engine.ReportDocument.Load(字符串文件名,OpenReportMethod openMethod,Int16 parentJob) 在 CrystalDecisions.CrystalReports.Engine.ReportClass.Load(字符串报告名称,OpenReportMethod openMethod,Int16 parentJob) 在 CrystalDecisions.CrystalReports.Engine.ReportDocument.EnsureLoadReport() 在 CrystalDecisions.CrystalReports.Engine.ReportDocument.SetDataSourceInternal(对象 val,类型类型) 在 CrystalDecisions.CrystalReports.Engine.ReportDocument.SetDataSource(DataSet dataSet)**

在这段时间监视任务管理器时,我注意到,我在关闭水晶报表查看器窗口之前处理的水晶报表并没有释放报表/报表查看器消耗的内存。这实际上是导致问题的原因。有没有其他方法可以正确处理水晶报表对象?

以下是连续加载报告时发生异常的屏幕截图: Image

这是我的代码块

CReportManager.cs

private bool GenerateReport(object oValue, bool bNeedPreview)
{
    Reports.crtSampleReport ocrtSample = null ;
    System.Drawing.Printing.PrintDocument doctoprint = null ;

    // its a usercontrol placed on this assembly
    PopUp.ucManagePrintPreview oPrintPreview = null;

    try
    {
        //pass the data to feed the report from other classes ( from same / different assembly ) 
        System.Data.DataSet dsPrintData = (System.Data.DataSet)oValue;

        if (dsPrintData == null || dsPrintData.Tables[2].Rows.Count == 0)
            throw new GOGGeneralHelpers.CGOGCustomException(
                "Print Data is Null", "No Data Available To Print", GOGGeneralHelpers.EnumLogType.ERR);

        ocrtSample = new Reports.crtSampleReport( ) ;
        ocrtSample.SetDataSource( dsPrintData ) ;
        ocrtSample.PrintOptions.PaperOrientation = CrystalDecisions.Shared.PaperOrientation.Portrait;

        System.Windows.Forms.DialogResult enDialogResult = System.Windows.Forms.DialogResult.OK;

        if (bNeedPreview)
        {     
            // if user want to view the preview before printing the report then its loads 
            // to a crystal report viewer placed on a usercontrol on this same assembly

            oPrintPreview = new PopUp.ucManagePrintPreview();
            oPrintPreview.FillReport( ocrtSample ) ;

            //a Window object placed on another assembly
            EHRPresentationBaseClassLibrary.Popups.PopupWindow
                        oPopupWindow = new EHRPresentationBaseClassLibrary.Popups.PopupWindow( ) ;

            //add the user control object (with crystal report viewer) to this window object            
            oPopupWindow.SetPopupPage( oPrintPreview ) ;
            oPopupWindow.Title = "Print Preview";
            oPopupWindow.Width = GOGPresentationCommonClassesLibrary.CCurrentAppSettings.CurrentAppSettings.PageWidth * .9;
            oPopupWindow.Height = System.Windows.SystemParameters.PrimaryScreenHeight * .8;
            oPopupWindow.ShowDialog();
            enDialogResult = oPrintPreview.PageResult ;                   
        }

        if (enDialogResult == System.Windows.Forms.DialogResult.Cancel
                    || enDialogResult == System.Windows.Forms.DialogResult.None) return true;

        //// Read printer name from a config file ///////////////////////

        System.IO.StreamReader oReader = System.IO.File.OpenText("PrintConfig.bat");
        string sPrinterName = oReader.ReadLine();
        oReader.Close();

        doctoprint = new System.Drawing.Printing.PrintDocument( ) ;
        doctoprint.PrinterSettings.PrinterName = sPrinterName ;

        //validate readed printer name is valid or not
        if ( !doctoprint.PrinterSettings.IsValid )
            throw new GOGGeneralHelpers.CGOGCustomException(
                "Selected Printer is not Valid", "Selected Printer is not Valid", GOGGeneralHelpers.EnumLogType.ERR ) ;

        ///////////////////////////////////////////////////////////////

        ocrtSample.PrintOptions.PaperSize = CrystalDecisions.Shared.PaperSize.PaperA4;

        ocrtSample.PrintOptions.PrinterName = sPrinterName;
        ocrtSample.PrintToPrinter(0, false, 0, 0);
        bReturn = true ;
    }
    catch (GOGGeneralHelpers.CGOGCustomException oCGOGCustomException)
    {                
        GOGPresentationCommonClassesLibrary.CApplicationHelper.
                    ApplicationHelper.ShowUserMessage(oCGOGCustomException, false, false);
        GOGGeneralHelpers.CGOGClientLogWriter.ClientLogWriter.WriteLog(oCGOGCustomException);
    }
    catch (System.Exception oException)
    {
        //Write to log file
        GOGGeneralHelpers.CGOGClientLogWriter.ClientLogWriter.WriteLog(oException);

        //Showing message to user
        GOGPresentationCommonClassesLibrary.CApplicationHelper.
                    ApplicationHelper.ShowUserMessage("Unexpected error on printing", oException, false, false);
    }

    // disposing the crystal report object
    // here is the issue its not releasing consumed memeory
    ocrtSample.Close(); 
    ocrtSample.Dispose();
    ocrtSample = null;

    doctoprint.Dispose();
    doctoprint = null;

    // disposing the crystal report viewer object
    oPrintPreview.ClearReportViewer();

    //this is also not working
    System.GC.Collect();
}

PopUp.ucManagePrintPreview.cs

//Function to load selected report to crystal report viewer
public void FillReport(CrystalDecisions.CrystalReports.Engine.ReportClass oReport) 
{
    MyCrystalReportViewer.ReportSource = oReport;
    MyCrystalReportViewer.ShowPrintButton = true;
}

//Function for dispose crystal report viewer object 
public void ClearReportViewer()
{
    MyCrystalReportViewer.ReportSource = null;
    MyCrystalReportViewer.Dispose();            
}

【问题讨论】:

    标签: c# wpf crystal-reports report


    【解决方案1】:

    我认为这里真正的问题是例外。内存由 GC 处理。 deletefree 的非托管方面可能并不多,这就是为什么任务管理器中的内存在释放几个字节时可能不会改变的原因。

    除此之外,我观察到只有在 Crystal-Reports 找不到您提供的报告(-文件)时才会发生此异常,类似于 FileNotFoundException。您提供的堆栈跟踪还显示了对各种 CR 内部 Load 方法的许多调用。

    【讨论】:

    • @Blacktempel..感谢您的回复..报告有图片,大小约为8mb(rpt文件),请看这两张图片在加载报告之前Imgur加载报告后(~ 5 - 7 次)Imgur 每次加载此报告后,应用程序的大小约为 45-50 mb,如果达到 ~700-760 mb,则报告将停止(就像我在第一篇文章中提到的屏幕截图) .我认为报告查看器有一个缓冲区大小:在达到该点之后,抛出此异常。
    猜你喜欢
    • 1970-01-01
    • 2020-09-17
    • 2011-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-28
    相关资源
    最近更新 更多