在 Crystal Reports for Visual Studio 项目中优化可伸缩性的另一种方法是使用可用的 Close() 方法之一来释放报表使用的内存。
提供两种 Close() 方法:
- 与 Crystal Reports 配合使用的 ReportDocument.Close()。
- 与 RAS SDK 配合使用的 ReportClientDocument.Close()。
ReportDocument.Close() 方法
在使用 Crystal Reports for Visual Studio 时,可以使用 ReportDocument.Close() 方法来释放 Crystal 报表在 Web 服务器上消耗的内存。
如何访问 ReportDocument.Close() 方法取决于报表是嵌入式报表还是非嵌入式报表:
- 如果是嵌入式报表,则会生成一个以代码表示报表的报表包装类。此报表包装类继承自 ReportDocument,并且通过继承来访问 Close() 方法。
- 如果是非嵌入式报表,则会将其从文件目录加载到 ReportDocument 的一个实例,然后直接从 ReportDocument 类访问 Close() 方法。
注意有关嵌入式报表和非嵌入式报表的更多信息,请参见“应该使用嵌入式报表还是非嵌入式报表?”。
Crystal 报表和 ReportDocument 的实例各自都会消耗内存。从内存中释放 ReportDocument 时,报表继续使用内存。
例如,当 Web 页完成加载时,ReportDocument 实例会退出作用域。在 .NET 的垃圾回收功能处理 ReportDocument 实例时,会从 Web 服务器中释放 ReportDocument 实例使用的内存。
但是,报表本身仍保留在 Web 服务器上的内存中。无法删除报表,这是因为访问报表的 ReportDocument 实例不再存在。当这些情况在高度伸缩的环境中重复出现时,Web 服务器上的内存中充满了不再被访问的报表。
若要解决该问题,请调用 ReportDocument.Close() 方法。此操作将在 Web 服务器上关闭报表本身,并且为其他报表释放内存。
何时调用 ReportDocument.Close() 方法
在显示报表之前不应在页面上调用 ReportDocument.Close() 方法,这是因为如果再次引用报表,即使报表已关闭,ReportDocument 也将会重新打开该报表。只应在显示过程完成后调用 Close() 方法。
调用 Close() 方法的正确时间是在 Page_Unload 事件期间。
ReportClientDocument.Close() 方法
当使用非托管 RAS 或托管 RAS 服务器时,报表将存储在报表应用程序服务器上,但是,它们在 Web 服务器上由一个 ReportClientDocument 实例表示。如果 ReportClientDocument 实例退出了作用域并且未调用 ReportClientDocument.Close() 方法,则报表应用程序服务器会在内存中一直打开报表(即使不再访问该报表)。当这些情况在高度伸缩的环境中重复出现时,报表应用程序服务器的内存中充满了在 Web 服务器上不再被访问的报表。
若要解决该问题,请调用 ReportClientDocument.Close() 方法。此操作会在报表应用程序服务器上关闭报表,并且为其他报表释放内存。
何时调用 ReportClientDocument.Close() 方法
在显示报表之前不应在页面上调用 Close() 方法,这是因为报表必须在服务器上保持打开,直到显示过程完成。
对于 ReportClientDocument 实例,Close() 方法会立即关闭报表,并且无法重新打开报表。因此,如果在报表显示之前调用 Close() 方法,将无法访问报表,并且会引发异常。
调用 Close() 方法的正确时间是在 Page_Unload 事件期间。