我已经编写了一个小型C#应用程序来使用Crystal Reports将报告保存为pdf。我遇到的问题是,当我保存更多的报告时,我的应用程序的句柄不断增加,并且我可以看到新的数据库连接正在创建,并且在保存每个报告后保持打开状态。最终,应用程序从Crystal发出异常说'数据库登录错误',或者我得到一个C++运行时错误,抱怨'R6025:纯虚函数调用'。Crystal Reports ReportDocument泄漏句柄
我正在查看使用process explorer的应用程序句柄,按照this technique。我正在使用MS SQL Server的活动监视器检查数据库连接。每个保存的报告导致另外100个打开句柄来处理'信号量'和'事件'以及2个数据库连接。
我相信我通过调用Close()然后Dispose(),正如here所述正确地处理报告。网络上的其他建议包括手动关闭数据库连接(Crystal reports - close the database connection)并调用GC.Collect(),但是没有一个适用于我的情况。
一些环境细节
- 的Visual Studio 2012
- C#控制台应用程序针对.NET 4.5.1运行
- 数据库:MSSQL Server 2012的
- 水晶报表的.NET Framework 4.0,版本13.09 .1312
- 使用SAP数据库连接的Crystal Report文档(这很重要 - 请参阅答案)
这里表现出了同样的问题一个示例应用程序:
using System;
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
namespace ExampleConsoleApp
{
class Program
{
static void Main(string[] args)
{
while (true)
{
SaveReport();
}
}
static void SaveReport()
{
Console.WriteLine("loading report...");
ReportDocument rpt = new ReportDocument();
rpt.Load("test.rpt");
rpt.SetDatabaseLogon("username", "password");
foreach (IConnectionInfo info in rpt.DataSourceConnections)
{
info.IntegratedSecurity = false;
info.SetConnection("SQL", "our_database", "username", "password");
}
rpt.ExportToDisk(ExportFormatType.PortableDocFormat, "test.pdf");
WaitForKeypress("about to dispose report");
// attempt to manually close tables/database links
// none of the following commented code has had any effect
// foreach (TableLink tl in rpt.Database.Links)
// {
// tl.Dispose();
// }
// rpt.Database.Links.Reset();
// rpt.Database.Links.Dispose();
// foreach (Table table in rpt.Database.Tables)
// {
// table.Dispose();
// }
// rpt.Database.Tables.Reset();
// rpt.Database.Tables.Dispose();
// rpt.DataSourceConnections.Clear();
// rpt.Database.Dispose();
rpt.Close();
rpt.Dispose();
// rpt = null;
// GC.Collect();
WaitForKeypress("disposed");
}
private static void WaitForKeypress(string msg = "press a key...")
{
Console.WriteLine(msg);
Console.ReadLine();
}
}
}
有人能告诉我什么,我做错了什么?