views:

242

answers:

6

in c#, i am deserializing an object of a type that implements IDisposable with the following statement (for illustration only).

XmlSerializer s = new XmlSerializer(typeof(MyDisposable))
MyDisposable o = (MyDispoable)s.Deserialize(filepath);

afaik, the serializer tries to construct the object using the default ctor and assigning all public properties and fields subsequently. In case there is any exception raised, i won't get my hands on the constructed object.

so, my question is if there is any way to make sure yet allocated resources are freed automatically. i am aware of the Dispose(bool disposing)-'pattern' implementing an explicit finalizer, but i'd feel more comfortable with freeing any resources explicitely (i.e. deterministically).

+2  A: 

It seems the unusual case for a DTO to actually have resources to deallocate, so I can understand if it doesn't provide IDisposable support on failure (my own serializer doesn't, either - so I certainly can't criticize).

Perhaps change your class so that if it does have resources to dispose, it takes those resources lazily (i.e. not just when the type is deserialized).

XmlSerializer doesn't support callbacks, otherwise the final callback would be a possible option to eagerly load resources (a bit hacky, though).

Marc Gravell
The lazy approach sounds like the most sensible solution
RichardOD
Guess you are right about the DTO-should-not-own-resources point. I was trying to get around the explicit DTO approach and use the dotnet xmlserializer out of the box. however, seems like this is rather problmetic in my case (as always, when trying to xml-serialize nontrivial classes)---.
A: 

Does your default constructor do something that would require a dispose? If yes, is this a good idea (especially for an object meant to be serialized in xml)? If no, then why are you worrying about it? Leave it for the garbage collector...

[Edit: Removed point about public fields, since its incorrect]
I'm also leaving this answer available for any educational value it may have -> read Marc's comment

Nader Shirazie
Public fields are assigned (although you shouldn't have public fields in the first place, of course); it is private members that are not. And it isn't just the constructor that you need to consider - it could fail at any point, and it could be unrelated to this class / instance.
Marc Gravell
Silly me... i'm so used to having only private fields, i forgot about the difference...And good point about other possible failures...
Nader Shirazie
A: 

If any exception is raised inside XmlSerializer.Deserialize method, it will propagate to the next catch method, and your object (o) will not be assigned. So unless you are using the properties setters to allocate some unmanaged resources during deserialization, I don't see why you should be concerned with manually disposing the object.

But if your class does allocate unmanaged resources, implementing IDisposable properly will mean that you will also release unmanaged resources from your object's finalizer, so that should be enough. There is no other way to call Dispose() on an object that didn't get assigned in the first place.

Having said that, I must admin that I've had several occasions where XmlSerializer would hang if the xml file was not completely valid during deserialization - so I ended up doing schema validation before deserialization, just to be sure everything goes fine.

Groo
A: 

How about calling GC.Collect(0, GCCollectionMode.Forced) after getting the exception?

anonymous
i wouldn't dare to... way to ugly
but it works :-P LOL
anonymous
you should never force GC explicitly.
Stan R.
+1  A: 

A using clause is what you use to deterministically free resources

using (MyDisposible o = (MyDisposible)s.Deserialize (filepath)) { // Do stuff with 0 }

I would question why you want to do this though. In C# you only want to deterministically free things if they're tied to an external physical resource like an SQL connection or a File.

A garbage collector is asymptotically more efficient than manual memory management and it's good practice to allow memory references to simply go out of scope to be freed.

A: 

Disposer and Finalizer are NOT the same thing in C#.

A disposer implements a call to explicitly dispose your resources used, but not the memory in them. The user of your object is required to call this.

You can use a finalizer in C# to guarantee that even if your disposer isn't called that you still don't leak resources. i.e .Net guarantees that it will try to run your disposer before it actually garbage collected.

XmlSerializer is responsible in it's call not to leak memory if there is an exception in the call. If this happens then you will have found a bug in .Net and feel free to report it. If you call deserialize and it throws an exception, you don't get the object back, it's gone...

.Net's garbage collector works by the way, it's one of the freebies you get with a managed language, in that you don't have to worry about cleaning up your memory (in most cases) so you can focus more on what your code is doing and get that right.

Spence
@Spence: What's this an answer to? I saw no reason to believe the OP thinks the two are the same. OBTW, never heard the term "Disposer" before.
John Saunders
Clarification in paragraphs 1, 2, 3. answer in 4/5. I believe I'm dealing with a C++ coder so I wanted to clarify the difference between a disposer and a finalizer which is a common mistake made by those crossing the chasm.
Spence