如何清理Crystal Reports ReportDocument对象使用的资源是最佳方式?

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)”中,“report”对象可以被处理多次。为避免生成System.ObjectDisposedException,您不应在一个对象上调用Dispose超过一次。

现在显然我可以改变代码以避免这个CA警告,但我的问题是:我应该吗?

Crystal Reports ReportDocument.Close()方法是否做好了处理资源清理的所有工作? 这个消息似乎表明Close方法调用了Dispose方法,但这似乎并不正确。

任何建议将不胜感激。

2个回答

3
虽然网络上有很多关于内存正确使用和任务完成后清理已使用内存的信息,例如在MSDN:IDisposable.Dispose或者Stackoverflow:Disposing and Setting to null中。这导致了一个流行的编码约定:如果可以调用Dispose,则应该这样做。
这个约定适用于像FileStream和SqlDataReader(等等)这样的对象,在这些对象中你可以同时使用Close和Dispose方法,而调用Dispose会调用Close。
我没有考虑到“水晶因素”。无论你喜欢还是讨厌他们,他们总是做一些不同寻常的事情。在这个SAP SDN文章的第二个回复中进行更多搜索之后,一个SAP员工似乎发布了Close方法的代码。如你所见,在清除和处理组成ReportDocument对象的所有元素之后,它也调用了ReportDocument.Dispose方法。
尽管如此,不知道Dispose方法如何实现(你可以推测代码以其目前的形式工作得很好),你应该按照正确的约定编写代码并调用Dispose方法或在Using语句中声明它。只需忽略CA警告即可。

1

根据this的说法,“Close() ... 释放报告使用的内存。” 这表明Close()调用Dispose(),因此在使用语句和Close()中都有可能是多余的。


这似乎违反了编码约定,即如果您已经完成了一个类型实现了IDisposable的对象,则应调用其Dispose()方法,或者您可以使用using块来执行此操作。 - Fooksie
我检查了汇编代码,发现Close方法没有调用Dispose。 - LostInComputer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接