Apo*_*fix 7 .net c# memory-leaks crystal-reports winforms
过去几天我一直在研究这个问题,我似乎无法弄明白.
我有一个c# WinForms应用程序使用它ReportDocument来加载报表并将其放入Crystal Report Viewer,以便用户可以预览它.目的是预览不同的统计信息,表单永远不会关闭.有一个计时器可以运行并向查看器加载不同的报告.
当发生这种情况时,内存使用和句柄(我可以在任务管理器中看到它们)不断增加.当应用程序启动时,它使用大约30 MB,当它运行10分钟时,它使用大约200 MB并且它不断增加.
我在互联网上阅读了很多关于这个问题的内容,我发现ReportDocument需要关闭和处理查看器.不幸的是,这并没有解决它.报告中的连接类型OLE DB(ADO)是从SQL Server数据库中检索数据.
简单地说,Form1有一个计时器,当它过去时它会处理Crystal Reports Viewer并调用垃圾收集器.然后加载新报告.
这是我的示例代码
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;
}
}
Run Code Online (Sandbox Code Playgroud)
问题来自数据库连接,因为如果我加载本地报告,它可以正常工作.但是我做错了什么?
使用Crystal Report来清理它用内存创建的混乱是非常棘手的.(对SAP没有违法)
你必须先关闭并处理掉 ReportDocument
rpt.Close();
rpt.Dispose();
Run Code Online (Sandbox Code Playgroud)
然后将空值分配给ReportViewer和dispose.
CRViewer.ReportSource=null;
CRViewer.Dispose();
CRViewer=null;
Run Code Online (Sandbox Code Playgroud)
最后,你必须做两次通过GC收集.
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Run Code Online (Sandbox Code Playgroud)
请注意,通常不建议调用GC.Collect(),但有时当内存太多问题而第三方COM组件像水晶报告有问题处理时,我们可能不得不走这条路.
| 归档时间: |
|
| 查看次数: |
4824 次 |
| 最近记录: |