2014-05-16 58 views
2

我已经编写了一个小型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(); 
     } 
    } 
} 

有人能告诉我什么,我做错了什么?

回答

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