数据库连接导致 CrystalReports ReportDocument 内存泄漏
CrystalReports ReportDocument memory leak with database connections
过去几天我一直在研究这个问题,但我似乎无法弄清楚。
我有一个 c#
WinForms
应用程序,它使用 ReportDocument
加载报告并将其放入 Crystal 报告查看器,以便用户可以预览它。目的是预览不同的统计数据并且表单永远不会关闭。有一个计时器可以运行并将不同的报告加载到查看器中。
虽然发生这种情况,但内存使用量和句柄(我可以在任务管理器中看到它们)不断增加。当应用程序启动时,它使用大约 30 MB,当它运行 10 分钟时,它使用大约 200 MB,并且还在不断增加。
我在网上看了很多关于这个问题的资料,发现 ReportDocument
和 Viewer 都需要关闭和处理。不幸的是,这并不能解决问题。报告中的连接类型是 OLE DB(ADO)
,因为数据是从 SQL Server
数据库中检索的。
简而言之,Form1 有一个计时器,当计时器超时时,它会处理 Crystal Reports Viewer
并调用垃圾收集器。然后加载新报告。
这是我的示例代码
表格 1:
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;
}
}
问题出在数据库连接上,因为如果我加载本地报告,它工作正常。但是我做错了什么?
Crystal 报告 清理内存造成的混乱非常棘手。 (无意冒犯 SAP)
您必须先关闭并处理 ReportDocument
rpt.Close();
rpt.Dispose();
然后将空值分配给 ReportViewer
并处理。
CRViewer.ReportSource=null;
CRViewer.Dispose();
CRViewer=null;
最后,您必须进行两次 GC 收集。
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Please note that it is generally not recommended to call GC.Collect() but sometimes when memory is too much of an issue and third party COM component's like crystal report has issue with getting disposed properly, we may have to go this route.
我找到了解决方法。 100% 工作。请安装 crystal 报告运行时版本 13_0_26。它为我修好了。最多只需要 100 mb 就可以生成 100 份报告。
新版本可能与您的 nuget 包不兼容,因此请相应地更新您的参考资料。
过去几天我一直在研究这个问题,但我似乎无法弄清楚。
我有一个 c#
WinForms
应用程序,它使用 ReportDocument
加载报告并将其放入 Crystal 报告查看器,以便用户可以预览它。目的是预览不同的统计数据并且表单永远不会关闭。有一个计时器可以运行并将不同的报告加载到查看器中。
虽然发生这种情况,但内存使用量和句柄(我可以在任务管理器中看到它们)不断增加。当应用程序启动时,它使用大约 30 MB,当它运行 10 分钟时,它使用大约 200 MB,并且还在不断增加。
我在网上看了很多关于这个问题的资料,发现 ReportDocument
和 Viewer 都需要关闭和处理。不幸的是,这并不能解决问题。报告中的连接类型是 OLE DB(ADO)
,因为数据是从 SQL Server
数据库中检索的。
简而言之,Form1 有一个计时器,当计时器超时时,它会处理 Crystal Reports Viewer
并调用垃圾收集器。然后加载新报告。
这是我的示例代码
表格 1:
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;
}
}
问题出在数据库连接上,因为如果我加载本地报告,它工作正常。但是我做错了什么?
Crystal 报告 清理内存造成的混乱非常棘手。 (无意冒犯 SAP)
您必须先关闭并处理 ReportDocument
rpt.Close();
rpt.Dispose();
然后将空值分配给 ReportViewer
并处理。
CRViewer.ReportSource=null;
CRViewer.Dispose();
CRViewer=null;
最后,您必须进行两次 GC 收集。
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Please note that it is generally not recommended to call GC.Collect() but sometimes when memory is too much of an issue and third party COM component's like crystal report has issue with getting disposed properly, we may have to go this route.
我找到了解决方法。 100% 工作。请安装 crystal 报告运行时版本 13_0_26。它为我修好了。最多只需要 100 mb 就可以生成 100 份报告。 新版本可能与您的 nuget 包不兼容,因此请相应地更新您的参考资料。