Skip to Content
0
May 26 at 07:49 PM

Memory Leak Issue in CrystalReportsViewer

92 Views Last edit May 26 at 08:30 PM 3 rev

Hi,

I am using WPF .NET Framework 4.7.2 with SAP Crystal Report 13.0.4000.0.

Below code is to Display the SAP Crystal Report in WPF Window in a separate view.

Each time when I press a button in the menu it will opened a separate window to display the SAP report using the below code.

When I close the report window and reopen it the memory got increasing increasing.

Could you please check and let me know how do I clear the Memory Leak Issue(Collect the garbage)

XAML File (ReportView.xaml)
<Window x:Class="WPFReportDisplay.ReportView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPFReportDisplay"
     xmlns:Viewer="clr-namespace:SAPBusinessObjects.WPF.Viewer;assembly=SAPBusinessObjects.WPF.Viewer"
        mc:Ignorable="d"
        Title="ReportView" Height="450" Width="800"
        Unloaded="Window_Unloaded">

<Grid>
        <Viewer:CrystalReportsViewer Grid.Column="1" Name="TicketViewer" ShowToggleSidePanelButton="False" ShowLogo="False" ToggleSidePanel="None" />
    </Grid>        
XAML.cs File (ReportView.xaml.cs)
        public ReportView()
        {     
             TicketViewer.ViewerCore.ReportSource = ConfigureReportDocument(); 
             TicketViewer.Owner = this;
        }

        private ReportDocument ConfigureReportDocument()
        {
            string sReportPath = "Path";
            ReportDocument myReportDocument = new ReportDocument();
            myReportDocument.Load(sReportPath);      

            ConnectionInfo myConnectionInfo = new ConnectionInfo
            {
                ServerName = "",DatabaseName = "",UserID = "",Password = ""
            };
     
            foreach (Table table in myReportDocument.Database.Tables)
            {
                TableLogOnInfo logOnInfo = table.LogOnInfo;
                logOnInfo.ConnectionInfo = myConnectionInfo;
                table.ApplyLogOnInfo(logOnInfo);
            }

            foreach (ParameterField myParameterField in myReportDocument.ParameterFields)
            {
                if (myParameterField.Name == "TransactionNumber")
                {
                    myReportDocument.SetParameterValue("TransactionNumber", "1");
                }
            }
            return myReportDocument
         }


    private void Window_Unloaded(object sender, RoutedEventArgs e)
    {          
       var objRptDocViewer = (ReportDocument)this.TicketViewer.ViewerCore.ReportSource;
       foreach (CrystalDecisions.CrystalReports.Engine.Table table in objRptDocViewer.Database.Tables)
       {
           table.Dispose();
       }
       foreach (ReportDocument subReport in objRptDocViewer.Subreports)
       {
           foreach (CrystalDecisions.CrystalReports.Engine.Table table in subReport.Database.Tables)
           {
                        table.Dispose();
           }
           subReport.Database.Dispose();
           subReport.Close();
           subReport.Dispose();
        }


                objRptDocViewer.Database.Dispose();
                objRptDocViewer.Close();
                objRptDocViewer.Dispose();


                this.TicketViewer.ViewerCore.ParameterFieldInfo.Clear();
                this.TicketViewer.ViewerCore.Content = null;
                this.TicketViewer.ViewerCore.Dispose();
                this.TicketViewer.Owner = null;
                this.TicketViewer = null;


                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
            
    }


Thanks In Advance !