11

我正在开发一个使用 Crystal Reports 进行报告的应用程序。它在 ReportDocument 对象中打开给定的报表,执行它需要执行的操作,然后关闭报表。

using (var report = OpenReport(reportSourceInfo))
{
    // Do stuff with the report
    report.Close();
}

OpenReport 方法对源文件进行一些验证并返回一个打开的 ReportDocument 对象。

测试表明,这段代码完成了它应该做的事情,并且似乎没有任何问题。我真正寻求建议的问题是,当我对报告项目进行代码分析 (CA) 构建时,我收到以下 CA 消息:

CA2202:Microsoft.Usage:对象“报告”可以在方法“CrystalReportingProvider.ReportExecute(ReportSourceInformation)”中多次处理。为避免生成 System.ObjectDisposedException,您不应在一个对象上多次调用 Dispose。

现在显然我可以更改代码,所以我不会收到这个 CA 警告,但我的问题是我应该这样做吗?

Crystal Reports ReportDocument.Close() 方法是否可以正确处理资源清理?该消息似乎表明 Close 方法调用了 Dispose 方法,但这似乎并不正确。

任何意见,将不胜感激。

4

2 回答 2

3

虽然网络上有大量关于正确使用内存和任务完成时相应清理已用内存的信息,例如MSDN:IDisposable.DisposeStackoverflow:Disposing and Setting to null。这产生了流行的编码约定,如果您可以调用 Dispose,那么就这样做。

此约定适用于像 FileStreams 和 SqlDataReader(以及其他)这样的对象,您同时拥有 Close 和 Dispose 方法,并且调用 Dispose 会调用 Close。

我没有考虑到的是“水晶因素”。喜欢或厌恶他们,他们做事……不同。在对这篇SAP SDN 文章的第二个回复中进行了很多在线搜索之后,SAP 员工似乎发布了 Close 方法的代码。如您所见,在清除和处置构成 ReportDocument 对象的所有元素后,它也调用了 ReportDocument.Dispose 方法。

尽管如此,并且在不知道 Dispose 方法是如何实现的情况下(正确地假设代码确实以其当前形式工作),您应该按照正确的约定进行编码并调用 Dispose 方法或在 Using 语句中声明它。只需抑制 CA 警告。

于 2012-02-08T01:55:53.090 回答
1

好吧,根据这个,“Close() ...释放报告使用的内存。” 这表明 Close() 调用了 Dispose(),因此同时使用 using 语句和 Close() 将是多余的。

于 2012-02-07T20:51:23.690 回答