I have the function below which is used to serialize an object without adding the XML declaration. I've just opened the project containing it an Visual Studio 2012 and the Code Analysis is coming up with the 'CA2202: Do not dispose objects multiple times' warning.
Now in other cases I've fixed this warning by removing an [object].Close that wasn't needed but in this case I can't see what needs to be altered and the help for the warning while being accurate isn't exactly informative as to how it is caused or how to fix it.
What exactly is causing the warning to display and how can I refactor to avoid it?
''' <summary>
''' Serialize an object without adding the XML declaration, etc.
''' </summary>
''' <param name="target"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function SerializeElementToText(Of T As New)(target As T) As String
Dim serializer As New XmlSerializer(GetType(T))
'Need to serialize without namespaces to keep it clean and tidy
Dim emptyNS As New XmlSerializerNamespaces({XmlQualifiedName.Empty})
'Need to remove xml declaration as we will use this as part of a larger xml file
Dim settings As New XmlWriterSettings()
settings.OmitXmlDeclaration = True
settings.NewLineHandling = NewLineHandling.Entitize
settings.Indent = True
settings.IndentChars = (ControlChars.Tab)
Using stream As New StringWriter(), writer As XmlWriter = XmlWriter.Create(stream, settings)
'Serialize the item to the stream using the namespace supplied
serializer.Serialize(writer, target, emptyNS)
'Read the stream and return it as a string
Return stream.ToString
End Using 'Warning jumps to this line
End Function
I tried this but it doesn't work either:
Using stream As New StringWriter()
Using writer As XmlWriter = XmlWriter.Create(stream, settings)
serializer.Serialize(writer, target, emptyNS)
Return stream.ToString
End Using
End Using 'Warning jumps to this line instead
If the class inherits from a class that implements IDisposable it must call the Dispose(), or Dispose(bool) method of the base class from within its own implementation of Dispose() or Dispose(bool), respectively. This ensures that all resources from the base class are properly released.
A correctly implemented Dispose method can be called multiple times without throwing an exception. However, this is not guaranteed and to avoid generating a System. ObjectDisposedException you should not call Dispose more than one time on an object.
The dispose pattern is used for objects that implement the IDisposable interface, and is common when interacting with file and pipe handles, registry handles, wait handles, or pointers to blocks of unmanaged memory. This is because the garbage collector is unable to reclaim unmanaged objects.
Dispose method must be called explicitly, objects that implement IDisposable should also implement a finalizer to handle freeing resources when System. IDisposable. Dispose is not called. By default, the garbage collector will automatically call an object's finalizer prior to reclaiming its memory.
It is a false warning, caused by XmlWriter disposing the stream you pass. Which makes your StringWriter disposed twice, first by XmlWriter and again by your Using statement.
This is not a problem, disposing .NET framework objects twice is not an error and doesn't cause any trouble. It could be a problem if the Dispose() method is poorly implemented, FxCop doesn't take its chances to not tell you about it because it isn't otherwise smart enough to know if a Dispose() method is correct.
There is not any way to rewrite the code to avoid a warning. StringWriter doesn't actually have anything to dispose so moving it out of the Using statement is okay. But that will produce another warning, CA2000. Best thing to do is to just ignore this warning. Use the SuppressMessageAttribute if you don't want to look at it again.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With