【问题标题】:Crystal reports - close the database connection水晶报表——关闭数据库连接
【发布时间】:2009-04-07 06:17:24
【问题描述】:

这是在 C#、Visual Studio 2008、VS2008 自带的水晶报表中

我有一个位于 DLL 中的水晶报表查看器表单。 DLL 负责加载水晶报表(基于报表文件名),并在窗体上显示报表。

当我完成水晶报表时,我在加载的报表文档对象上调用 dispose。但是,数据库连接仍然存在。

Crystal 似乎检测到有其他连接(从我的主应用程序)到同一个数据库,并保持其连接打开。当主应用程序数据库连接关闭时,水晶连接关闭。

有什么方法可以强制水晶关闭其连接,而不关闭主应用程序数据库连接?

【问题讨论】:

    标签: c# sql-server crystal-reports report


    【解决方案1】:

    您是如何连接到数据库的,通过设置身份验证在运行时创建自己的连接,还是让 Crystal 通过报表中存储的连接进行连接?如果您正在以任何方式、形状或形式进行自己的连接,则必须手动关闭连接并在处理报告之前调用 dispose。

    这很可能是内存泄漏。我以前经历过这些。 Crystal Reports 也存在内存泄漏问题,并且在他们的论坛上讨论了很多,但几年前我使用它时没有发布修复。我放弃了 Crystal 以寻求其他选择。

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题,只是我使用的是 Sybase。不久前,当我看到一个错误时,我发布了我编写的用于处理连接的代码(这不起作用)!我修复了错误,并且,交叉手指,现在它似乎工作了。我已经打开了近 100 份报告,而之前我无法打开 10 份。如果你尝试这个,请告诉我它是否适合你。

      这是我在关闭包含 Crystal Reports 查看器的窗口之前正在做的事情:

      var rd = (ReportDocument)crystalReportViewer1.ReportSource;
      foreach (Table table in rd.Database.Tables)
         table.Dispose();
      rd.Database.Dispose();
      rd.Close();
      rd.Dispose();
      GC.Collect();
      

      标记

      【讨论】:

        【解决方案3】:

        标记代码似乎在某种程度上缓解了这种情况,虽然它有点倒退,应该是这样的:

        ReportDocument rd = (ReportDocument) viewer.ReportSource;
        foreach (Table table in rd.Database.Tables)
            table.Dispose();
        viewer.ReportSource = null;
        rd.Database.Dispose();
        rd.Close();
        rd.Dispose();
        rd = (ReportDocument) viewer.ReportSource;  
        GC.Collect();
        

        这对我来说并没有完全堵住漏洞,但确实有帮助。

        【讨论】:

          【解决方案4】:

          我对 Crystal Reports 不太熟悉,但是由于包含 IDisposable 接口的继承链,许多对象具有无用的 Dispose() 方法。如果您在服务器上没有看到任何性能问题,请不要担心。 GC 准备好后会处理客户端上的连接。你不应该比GC更聪明,你只会让自己更头疼。

          并且,当 Dispose() 可用时始终调用(或使用{})。

          【讨论】:

          • 这真的是关于数据库连接。主应用程序具有恢复和备份数据库的功能。水晶数据库连接可以防止这种情况。我在谷歌上匆匆忙忙,处理报告会关闭连接,但前提是水晶是唯一连接的东西。
          • 我假设您使用的是 MSSQL,对吗?为什么不从那里使用内置的备份/恢复?
          • 因为该产品旨在供非技术人员使用。有两个菜单项说备份/恢复更容易理解,然后进入 sql management studio,以具有这些权限的用户身份登录等。
          • 我在使用“总是”的作品时会小心。您首先说许多对象有一个无用的 Dispose 方法,总是使用它或使用 then 是否有意义?
          【解决方案5】:
          connectDB();
          
          ReportDocument cryRpt = new ReportDocument();
          DataSet ds;
          cmd = new SqlCommand("Select * from LeaveJO where IDno = '" + textBox1.Text + "'", conn);
          
          da = new SqlDataAdapter(cmd);
          ds = new DataSet();
          da.Fill(ds, "LeaveJO");
                      cryRpt.Load(@"JOleave.rpt");
                      cryRpt.SetDataSource(ds);
          
                      TableLogOnInfos crtableLogoninfos = new TableLogOnInfos();
          TableLogOnInfo crtableLogoninfo = new TableLogOnInfo();
          ConnectionInfo crConnectionInfo = new ConnectionInfo();
          Tables CrTables;
          
          crConnectionInfo.ServerName = cs.serverName;
          crConnectionInfo.DatabaseName = cs.dbName;
          crConnectionInfo.UserID = cs.userID;
          crConnectionInfo.Password = cs.password;
          
          CrTables = cryRpt.Database.Tables;
          foreach (CrystalDecisions.CrystalReports.Engine.Table CrTable in CrTables)
          {
              crtableLogoninfo = CrTable.LogOnInfo;
              crtableLogoninfo.ConnectionInfo = crConnectionInfo;
              CrTable.ApplyLogOnInfo(crtableLogoninfo);
          }
          
          cryRpt.Refresh();
          //  cryRpt.PrintToPrinter(2, true, 1, 2);
          crystalReportViewer1.ReportSource = cryRpt;
          crystalReportViewer1.Visible = true;
          cryRpt.Dispose();
          conn.Dispose();
          

          【讨论】:

            【解决方案6】:

            您可以更改 CRConfig.xml 中的 timout 选项,以便自动关闭连接。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-12-06
              • 1970-01-01
              • 1970-01-01
              • 2010-10-28
              • 2020-04-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多