I've spent the past few days looking into that and I can't seem to figure it out.
I have a c#
WinForms
application that uses the ReportDocument
to load a report and put it into the Crystal Report Viewer, so that the user can preview it. The purpose is to preview different statistics and the form is never closed. There's a timer that runs and loads different reports into the viewer.
While that happens the memory usage and handles (I can see them in the task manager) keep increasing. When the application is started, it uses around 30 MB and when it runs for 10 minutes, it is then using around 200 MB and it keeps increasing.
I read a lot about this problem on the internet and I found that both the ReportDocument
and the Viewer need to be closed and disposed. Unfortunately, that doesn't fix it. The connection type in the reports is OLE DB(ADO)
as the data is retrieved from an SQL Server
database.
Briefly what happens is that Form1 has a timer that when elapses it disposes the Crystal Reports Viewer
and calls the garbage collector. And then loads the new report.
Here is the sample code that I have
Form1:
private ReportDocument rpt;
private void timer2_Tick(object sender, EventArgs e)
{
timer2.Enabled = false;
try
{
panel1.Hide();
if (rpt != null)
{
foreach (Table t in rpd.Database.Tables)
t.Dispose();
rpt.Close();
rpt.Dispose();
rpt = null;
GC.Collect();
}
panel1.Controls.Remove(CRVviewer);
if (CRVviewer != null)
{
CRVviewer.Dispose();
GC.Collect();
}
// The problem starts from here:
var report = navigationbar1.CurrentNode;
rpt = new ReportDocument();
rpt.Load(@report.Path, OpenReportMethod.OpenReportByDefault);
rpt.ReportOptions.EnableSaveDataWithReport = false;
rpt.SetDatabaseLogon(report.UserId, report.Password);
rpt.VerifyDatabase();
// It ends here
CRVviewer = new CrystalReportViewer();
CRVviewer.ReportSource = rpt;
CRVviewer.ShowLastPage();
pagecount = CRVviewer.GetCurrentPageNumber();
CRVviewer.ShowFirstPage();
panel1.Controls.Add(CRVviewer);
this.Update();
}
catch(Exception ex)
{
ProcessErrors(ex);
}
finally
{
timer2.Enabled = true;
}
}
The problem comes from the DB connections, because if I load a local report, it works fine. But what do I do wrong?