我无法修复代码分析规则CA2202

时间:2013-04-05 09:05:12

标签: c# itextsharp code-analysis

我有一个功能(请参阅下面的代码段)。

我启用了代码分析,并且我违反了CA2202规则。

编辑:我在pdfStamper上添加了关闭,否则PDF将被破坏)

  

CA2202:不要多次丢弃对象

     

方法实现包含可能导致在同一对象上多次调用IDisposable.Dispose或Dispose等效项(如某些类型的Close()方法)的代码路径。

在CA2202 MSDN页面(here)中,建议的修复无效。

如何在不必抑制此违规的情况下重写代码?

private byte[] DoGenerateFinishedGamePdf(int gameSessionLogId)
{
   var finishedGameCertificatePdfFile = httpServerUtilityWrapper.MapPath(ConfigurationManager.AppSettings["FinishedGameCertificateFile"]);

   var pdfReader = new PdfReader(finishedGameCertificatePdfFile); // note that PdfReader is not IDisposeable

   using (MemoryStream memoryStream = new MemoryStream())
   using (PdfStamper pdfStamper = new PdfStamper(pdfReader, memoryStream))
   {
      var fields = pdfStamper.AcroFields;
      fields.SetField("CityName", "It works!");

      pdfReader.Close();

      pdfStamper.FormFlattening = true;
      pdfStamper.FreeTextFlattening = true;
      pdfStamper.Close();

      return memoryStream.ToArray();
   }
}

2 个答案:

答案 0 :(得分:2)

啊,大家最喜欢的警告!在这种情况下,MemoryStream.Dispose是幂等的(当前实现什么都不做)所以它不是一个真正的问题,但是'fix'如下:

MemoryStream memoryStream = null;
try
{
  memoryStream = new MemoryStream();
  using (PdfStamper pdfStamper = new PdfStamper(pdfReader, memoryStream))
  {
    memoryStream = null;

    var fields = pdfStamper.AcroFields;
    fields.SetField("CityName", "It works!");

    pdfReader.Close();

    pdfStamper.FormFlattening = true;
    pdfStamper.FreeTextFlattening = true;
    pdfStamper.Close();

    return memoryStream.ToArray();
  }
}
finally
{
  if (memoryStream != null) memoryStream.Dispose();
}

由于PdfStamper'拥有'MemoryStream,它会在调用PdfStamper.Dispose时处理它,所以我们只需要在MemoryStream上调用Dispose,如果我们不处理PdfStamper,这只会在构造时发生PdfStamper失败了。

答案 1 :(得分:1)

这种情况正在发生,因为PdfStamper正在处理流,即使它不应该。它没有创建它并且不拥有它,因此没有业务处理它。

你的代码确实创建了流,它确实拥有它,所以它应该处理它是很自然的。如果PdfStamper没有不适当地处理流,那么嵌套使用就可以了。

您的第一步应该是提交错误报告/功能请求,以删除流的PdfStamper处置或至少可以避免。完成后,您可以非常安全地抑制CA2202违规,因为MemoryStream的双重处理不会产生任何有害后果。

BTW,PdfStamper.Dispose()调用PdfStamper.Close()(至少在版本5.4.0中),因此您应该能够删除PdfStamper.Close()调用。

相关问题