I cannot get rule CA2202 code analysis

I have a function (see code snippet below).

I have code analysis enabled and I get a CA2202 rule violation.

( edit : I added a closure to pdfStamper, otherwise the PDF will get corrupted)

CA2202: do not delete objects multiple times

The method implementation contains paths to codes that can lead to several IDisposable calls. Use either the Dispose equivalent, for example, the Close () method for some types, on the same object.

On the MSDN CA2202 page ( here ), the proposed fix does not work.

How can I rewrite the code without violating this violation?

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(); } } 
+4
source share
2 answers

Ah, all your favorite warnings! In this case, MemoryStream.Dispose is idempotent (the current implementation does nothing), so this is not a problem, however the β€œfix” looks like this:

 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(); } 

Since PdfStamper "owns" a MemoryStream, it will get rid of it when PdfStamper.Dispose is called, so we only need to call Dispose on a MemoryStream, unless we get rid of PdfStamper, which can happen only if PdfStamper does not work.

+2
source

This is because PdfStamper removes the stream, although it should not. He did not create it and does not own it, so he does not have a business managing it.

Your code really created the thread, and it really owns it, so it’s quite natural that it should dispose of it. If PdfStamper has not disposed of the stream inappropriately, everything will be okay with your enclosed needs.

Your first step should probably be to write a bug report / function request that removes the pdfstamper stream, or at least can be avoided. Once you do this, you can safely prevent a violation of CA2202, since a dual MemoryStream layout will not be detrimental.

BTW, PdfStamper.Dispose () call PdfStamper.Close () (at least in version 5.4.0) so that you can remove the call to PdfStamper.Close ().

+1
source

All Articles