Crystal Reports ReportDocument泄漏句柄

时间:2014-05-16 04:17:15

标签: c# sql-server crystal-reports

我编写了一个小型C#应用程序,使用Crystal Reports将报告保存到pdf。我遇到的问题是,当我保存更多报告时,我的应用程序的句柄不断增加,我可以看到新的数据库连接正在建立并在每个报告保存后保持打开状态。最终,应用程序从Crystal获得“数据库登录错误”的异常,或者我收到了抱怨'R6025:纯虚函数调用'的C ++运行时错误。

根据process explorer,我正在查看使用this technique的应用句柄。我正在使用MS SQL Server的活动监视器检查数据库连接。每个保存的报告都会导致“信号量”和“事件”以及2个数据库连接的另外100个打开句柄。

我相信我正在通过调用Close()然后调用Dispose()来正确处理报告,如上所述here。围绕Web的其他建议包括手动关闭数据库连接(Crystal reports - close the database connection)和调用GC.Collect(),但是没有一个在我的情况下有效。

一些环境细节

  • Visual Studio 2012
  • 针对.NET 4.5.1运行时的C#控制台应用程序
  • 数据库:MSSQL Server 2012
  • Crystal Reports for .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();
        }
    }
}

有人能告诉我我做错了吗?

1 个答案:

答案 0 :(得分:1)

您是否正在使用SAP B1的水晶报告? 如果是这样,这是在Windows Server上运行代码并在Crystal报表中使用SAP B1数据库连接类型的问题。我在Windows Server 2012上使用SAP B1中的Boyum Usability Pack时遇到了同样的问题。将Crystal报表中的连接类型更改为OLE(ADO)后,它工作正常。我认为SAP B1数据库连接类型存在问题,或者可能不适合用于此目的。

在youtube上观看此视频,其中介绍了如何将驱动程序设置为OLE(ADO)。 http://youtu.be/j7kpj2tR3d4