Click here to Skip to main content
15,899,026 members
Home / Discussions / C#
   

C#

 
Questionthread safe in Dispose method Pin
George_George14-May-08 2:57
George_George14-May-08 2:57 
AnswerRe: thread safe in Dispose method Pin
Christian Graus14-May-08 3:00
protectorChristian Graus14-May-08 3:00 
GeneralRe: thread safe in Dispose method Pin
George_George14-May-08 15:16
George_George14-May-08 15:16 
GeneralRe: thread safe in Dispose method Pin
Peter Josefsson Sweden14-May-08 16:08
Peter Josefsson Sweden14-May-08 16:08 
GeneralRe: thread safe in Dispose method Pin
George_George14-May-08 16:20
George_George14-May-08 16:20 
GeneralRe: thread safe in Dispose method Pin
Peter Josefsson Sweden14-May-08 17:00
Peter Josefsson Sweden14-May-08 17:00 
GeneralRe: thread safe in Dispose method Pin
George_George14-May-08 17:26
George_George14-May-08 17:26 
GeneralRe: thread safe in Dispose method Pin
Peter Josefsson Sweden15-May-08 8:51
Peter Josefsson Sweden15-May-08 8:51 
Thanks for the appreciation!

When English isn't your own language (which I assume it isn't for neither of us), it can be hard to understand even the good C#/CLR books sometimes. I have read a lot of good texts about the IDisposable interface over the last few years (there are even some excellent articles on CodeProject), but I must admit that it wasn't until recently that all the pieces of the puzzle fell into place. Sometimes you have to read the same thing (phrased differently) several times before you get it.

So, I'll try to summarize the most important points again (it should answer your follow-up questions as well), as short and concise as I can:

A: It is always legal to call Dispose() on an object more than once, for exactly one reason: The example I gave (and similar code) should always work even if something happens in DoSomeOtherStuff(). This means that a call to Dispose() should never cause an ObjectDisposedException - if the object is already disposed, Dispose() should just silently do nothing. Note that usually, the only place where this is acceptable is in an exception handler (as in my example).

B: It is always illegal to call any other method or property on an object after Dispose() has been called. And ideally, an ObjectDisposedException should always be thrown if that happens (but like I said, this is not always the case - sometimes very bad things such as unmanaged memory corruption or similar happen instead - even in some .NET Framework classes).

Some conclusions (some obvious, some not):

C: You may only call Dispose() on an object if a) you created the object, b) you haven't given away the reference to anyone and c) you're done with it. Can't be said too many times...

D: If you ever see an ObjectDisposedException, it is a bug. It should be fixed (yesterday), so it's fine to just crash (as long as you leave a clue as to why, meaning that if you're a service or a web application, you should log the exception before crashing - if you're a Windows app, you should display it and/or log it).

E: A repetition of rule C from a different angle: If you ever expose your reference to a disposable object (by returning it from a property or using it in a call into a class you don't control), you effectively give up your right to dispose of it. There are cases when it is OK to do differently, but they must be documented. For example: "If you dispose of a MyParent object, all MyChild objects created by it will also be disposed of, and may not be used again" (if I remember correctly, there are such relationships in the SqlClient namespace in the framework). In such cases it does make sense to deviate a bit from the basic rules.

F: Answering your original question - making the Dispose() method thread-safe is meaningless. It should only be called by the class that created the object, only when it will not be used again (even though additional Dispose() calls may be made by the same caller due to exception handlers) and only when nobody else can hold a reference to the object. Hence, the class creating the object has no reason whatsoever to call Dispose() from more than one thread. If someone comes up with a reason (I once did, actually - I called the same termination and cleanup routine from a worker thread that I exposed to clients when it died due to external problems), the caller is free to implement his own synchronization (I did in my termination routine).

G: A public IsDisposed property is entirely meaningless. If the code calling Dispose() doesn't know it did, it's broken (the example with the exception handler is the only exception - but since an extra Dispose() should cost less than a property check, the property still doesn't make sense).

H: The IDisposable interface is meant for classes holding unmanaged resources (including other disposable objects). Don't bother otherwise (unless you're writing an abstract class that would typically be implemented using unmanaged resources or disposable objects).

Finally, an example from the framework: If you create an Image from a BinaryStream you may think that you can dispose of the BinaryStream when that is done. Not so. The Image will not read the entire stream until it has to, and if the stream is a file it is even free to read the same part of the file several times when needed. Look at rule E. You showed the stream to the image, so you're no longer in control of it, and may not call Dispose(). In this particular case, you can dispose of the image (after making sure that nothing that has seen it is still around) and then of the stream.

Clear as mud?

Smile | :)

One more suggestions: Do read the articles on implementing the IDisposable interface here on CodeProject as well. There are some aspects (such as how exceptions in Dispose() should be handled, and how object inheritance comes into play) to it that I haven't mentioned. It's too complex for a forum post, and I don't remember all of it anyway...

Good Night!

--
Peter

GeneralRe: thread safe in Dispose method Pin
George_George16-May-08 20:42
George_George16-May-08 20:42 
GeneralRe: thread safe in Dispose method Pin
Peter Josefsson Sweden16-May-08 21:46
Peter Josefsson Sweden16-May-08 21:46 
AnswerRe: thread safe in Dispose method Pin
Peter Josefsson Sweden14-May-08 5:57
Peter Josefsson Sweden14-May-08 5:57 
GeneralRe: thread safe in Dispose method Pin
George_George14-May-08 15:21
George_George14-May-08 15:21 
QuestionDllImport question Pin
matt23lucier14-May-08 2:20
matt23lucier14-May-08 2:20 
AnswerRe: DllImport question Pin
Christian Graus14-May-08 2:38
protectorChristian Graus14-May-08 2:38 
AnswerRe: DllImport question Pin
Dario Solera14-May-08 2:46
Dario Solera14-May-08 2:46 
AnswerRe: DllImport question Pin
carbon_golem14-May-08 4:28
carbon_golem14-May-08 4:28 
AnswerRe: DllImport question Pin
matt23lucier16-May-08 8:16
matt23lucier16-May-08 8:16 
QuestionHow to include visio diagrams in C#.net application Pin
ysunil_7414-May-08 1:33
ysunil_7414-May-08 1:33 
AnswerRe: How to include visio diagrams in C#.net application Pin
Gareth H14-May-08 1:37
Gareth H14-May-08 1:37 
AnswerRe: How to include visio diagrams in C#.net application Pin
Simon P Stevens14-May-08 1:55
Simon P Stevens14-May-08 1:55 
QuestionHow can i obtain a textbox in my webbrowser and pass the text a windows form? Pin
solbyte14-May-08 1:19
solbyte14-May-08 1:19 
AnswerRe: How can i obtain a textbox in my webbrowser and pass the text a windows form? Pin
Christian Graus14-May-08 1:37
protectorChristian Graus14-May-08 1:37 
QuestionCrystal Report Pin
mehrdadc4814-May-08 0:40
mehrdadc4814-May-08 0:40 
AnswerRe: Crystal Report Pin
ChandraRam14-May-08 1:20
ChandraRam14-May-08 1:20 
QuestionOnPaintBackground Problem. Pin
hdv21214-May-08 0:21
hdv21214-May-08 0:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.