Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle exception thrown from Dispose?

Tags:

Recently, I was researching some tricky bugs about object not disposed.

I found some pattern in code. It is reported that some m_foo is not disposed, while it seems all instances of SomeClass has been disposed.

public class SomeClass: IDisposable {     void Dispose()     {        if (m_foo != null)        {           m_foo.Dispose();        }        if (m_bar != null)        {           m_bar.Dispose();        }        }      private Foo m_foo;      private Bar m_bar;  } 

I suspects that Foo.Dispose might throw a exception, so that following code is not executed so m_bar is not disposed.

Since Foo/Bar might be from third party, so it is not guaranteed to not throwing exception.

If just wrap all Dispose invocation with try-catch, the code will turn to be clumsy.

What's best practice to handle this?

like image 541
Morgan Cheng Avatar asked Jun 23 '09 03:06

Morgan Cheng


People also ask

Should Dispose throw exception?

Dispose method should not throw an exception. Dispose is often called as part of the cleanup logic in a finally clause. Therefore, explicitly throwing an exception from Dispose forces the user to add exception handling inside the finally clause.

What happens if exception occurs in using Block C#?

Answers. The exception is thrown, because there is no catch statement in the compiled code. If you handle the exception within the using block, your object will still be disposed in the compiler-generated finally block.

What does throwing an exception means?

The object, called an exception object, contains information about the error, including its type and the state of the program when the error occurred. Creating an exception object and handing it to the runtime system is called throwing an exception.

Why would you want to throw an exception?

Exceptions should be used for exceptional situations outside of the normal logic of a program. In the example program an out of range value is likely to be fairly common and should be dealt with using normal if-else type logic. (See the programming exercises.)


1 Answers

Its true that it can be pretty bad to leak out an exception of your dispose method, especially since stuff that implements IDisposable will usually specify a finalizer that will call Dispose.

The problem is that sweeping the problem under of the carpet by handling an exception may leave you with some very hard-to-debug situations. What if your IDisposable allocated a critical section of sorts that only gets released after dispose. If you ignore the fact that the exception happened, you may end up in deadlock central. I think failures in Dispose should be one of those cases where you want to fail early, so you can fix the bug as soon as its discovered.

Of course it all depends on the object being disposed, for some objects you may be able to recover, others not. As a general rule of thumb, Dispose should not throw exceptions when used correctly and you should not have to code defensively around exceptions in nested Dispose methods you are calling.

Do you really do not want to sweep an OutOfMemoryException under the carpet?

If I had a dodgy 3rd party component that arbitrarily threw exceptions on Dispose I would get it fixed AND host it in a separate process that I could tear down when it started playing up.

like image 115
Sam Saffron Avatar answered Nov 06 '22 04:11

Sam Saffron