A question for you all.
In my company, we are developing an application that runs inside Microsoft’s MVC framework.
The controller classes that we are implementing inherit from the MVC base class Controller. Example:
public class MyController: Controller
{
protected bool IsDisposed { get; set; }
… various methods…
}
The discussion we are having in the team centers around the Dispose() pattern. Essentially, this involves implementing the IDisposable interface, preferably according to the Microsoft-endorsed pattern.
See for example this link: http://msdn.microsoft.com/en-us/library/fs2xkftw%28v=vs.110%29.aspx
Interestingly, our controller classes do not own any resources, either managed or managed. As a result, the implementation of Dispose(bool) is greatly simplified:
protected override void Dispose(bool disposing)
{
IsDisposed = true;
base.Dispose(disposing);
}
There is some disagreement about the use (or need) of the IsDisposed property, that is used in the following method:
protected void ThrowIfDisposed()
{
if (IsDisposed) throw new ObjectDisposedException(“MyController”);
}
This method is then called at the beginning of every method that does "real" work. The thinking here is that a disposed object should not be used again, hence it should throw the ObjectDisposedException. The other opinion is that, since Dispose(bool) does “nothing” (other than setting the IsDisposed property and calling Dispose(bool) on the base class), the “disposed” object is not really in a state that is unusable, so there is no reason to throw. Therefore, there is no reason to even implement Dispose(bool).
An argument against this is that MyController should throw when it is disposed and one of its methods is called, so that its behaviour does not change should in future versions managed and/or unmanaged resources be added.
The argument against this last point is that MyController should never add any resources in future versions, but rather it should be derived from should the need to add resources occur in the future. An additional question is: why doesn’t the (library) class Controller implement ThrowIfDisposed() or something similar?
So, summarizing, faction one wants to implement Dispose(bool) and ThrowIfDisposed() as shown above, faction two thinks they are unnecessary and wants to do away with them.
I see merits in both viewpoints, cannot really make up my mind. Opinions?
Interestingly, our controller classes do not own any resources, either managed or managed.
Then you do not need the IDisposable pattern.
This method [ ThrowIfDisposed() ] is then called at the beginning of every method that does “real” work.
The qustion here is: Why?
If you do want to track a usable/abandoned state then just don't call it IsDisposed.
why doesn’t the (library) class Controller implement ThrowIfDisposed() or something similar?
Because it isn't useful.
Go back to the beginning: why did somebody think this was necessary? What is it for?
It seems you can just rip it out.
If an object receives a request after being disposed, the request should not fail for any reason other than ObjectDisposedException--meaning it shouldn't cause a NullReferenceException, yield garbage data, crash the system, or do any other such thing. That does not imply that the request shouldn't succeed--merely that ObjectDisposedException should be the only mode of failure.
As for IsDisposed, I can't really see much use for it in most cases. Code which doesn't know whether an object is disposed generally won't know much else enough about the object's state to know whether it might be unusable for some other reason; consequently, code that doesn't know whether an object is disposed generally shouldn't do anything with it except--in some cases--to Dispose it, and in most of those cases where one would want to call Dispose on an object if it hadn't already been disposed, one should simply call Dispose unconditionally. There could be some value in having a method MayNeedDisposing which would return true for objects with non-trivial Dispose methods until they've been disposed, but such a method could unconditionally return false for objects with null Dispose methods [in cases where a class would e.g. register a callback purely for the purpose of calling Dispose on something, testing MayNeedDisposing beforehand could be a useful optimization].
Finally, with regard to whether a class or interface should implement or inherit IDisposable, the issue is not whether the type itself acquire resources, but rather whether the last surviving reference to something that does acquire resources may be stored in that type. For example, even though the vast majority of IEnumerator<T> implementations don't acquire resources, some do, and in many such cases the only references to such objects will be stored in variables of type IEnumerator<T>, held by code that has no idea whether the objects in question have any resources or not. Note that non-generic IEnumerator doesn't implement IDisposable but some implementations acquire resources. As a consequence, code which calls IEnumerable.GetEnumerator will be required to call Dispose on the returned enumerator if it implements IDisposable. The fact that IEnumerator doesn't inherit IDisposable doesn't absolve code which receives an IEnumerator implementation that also implements IDisposable from the responsibility of calling Dispose--it merely makes it harder for such code to carry out that responsibility.
Faction two is absolutely right. Don't do it.
Implementing IDisposable in the way described and for the reasons given is a violation of at least three good principles.
You ain't gonna need it. http://c2.com/cgi/wiki?YouArentGonnaNeedIt
Do the simplest thing that could possibly work. http://www.xprogramming.com/Practices/PracSimplest.html
Keep it simple stupid. https://en.wikipedia.org/wiki/KISS_principle
It's just wrong on every level. Don't do it.
Related
In C#, if a class, such as a manager class, does not have resources, is there any benefit to having it : IDisposable?
Simple example:
public interface IBoxManager
{
int addBox(Box b);
}
public class BoxManager : IBoxManager
{
public int addBox(Box b)
{
using(dataContext db = new dataContext()){
db.Boxes.add(b);
db.SaveChanges();
}
return b.id;
}
}
Will there be any benefit in memory use when using BoxManager if it also implements IDisposable? public class BoxManager : IBoxManager , IDisposable
For example:
BoxManager bm = new BoxManager();
bm.add(myBox);
bm.dispose();//is there benefit to doing this?
There are only 2 reasons for implementing IDisposable on a type
The type contains native resources which must be freed when the type is no longer used
The type contains fields of type IDisposable
If neither of these are true then don't implement IDisposable
EDIT
Several people have mentioned that IDisposable is a nice way to implement begin / end or bookended operations. While that's not the original intent of IDisposable it does provide for a very nice pattern.
class Operation {
class Helper : IDisposable {
internal Operation Operation;
public void Dispose() {
Operation.EndOperation();
}
}
public IDisposable BeginOperation() {
...
return new Helper() { Operation = this };
}
private void EndOperation() {
...
}
}
Note: Another interesting way to implement this pattern is with lambdas. Instead of giving an IDisposable back to the user and hoping they don't forget to call Dispose have them give you a lambda in which they can execute the operation and you close out the operation
public void BeginOperation(Action action) {
BeginOperationCore();
try {
action();
} finally {
EndOperation();
}
}
There won't be a scrap of difference between the disposable and non-disposable version if you don't explicitly make use of the Dispose() method.
While your code wouldn't benefit from implementing IDisposable, I can't agree with other opinions here that state that IDisposable is only meant to (directly or indirectly) free native resources. IDisposable can be used whenever the object needs to perform clean up task at the end of it's lifetime span. It's extremely useful together with using.
A very popular example: in ASP.NET MVC Html.BeginForm returns an IDisposable. On creation, the object opens the tag, when Dispose is called it closes it. No native resources involved, yet still a good use of IDisposable.
No, there will be no benefit if you don't do something useful like releasing unmanaged resources that your class might hold in the Dispose method.
One major point of confusion, which may not be applicable in your case but arises often, is what exactly constitutes a "resource". From the perspective of an object, an unmanaged resource is something which an outside entity () is "doing"(*) on its behalf, which that outside entity will keep doing--to the detriment of other entitites--until told to stop. For example, if an object opens a file, the machine which hosts the file may grant that object exclusive access, denying everyone else in the universe a chance to use it unless or until it gets notified that the exclusive access isn't needed anymore.
(*) which could be anything, anywhere; possibly not even on the same computer.
(**) or some way in which the the behavior or state of an outside entity is altered
If an outside entity is doing something on behalf of an object which is abandoned and disappears without first letting the entity know its services are no longer required, the outside entity will have no way of knowing that it should stop acting on behalf of the object which no longer exists. IDisposable provides one way of avoiding this problem by providing a standard means of notifying objects when their services are not required. An object whose services are no longer required will generally not need to ask any further favors from any other entities, and will thus be able to request that any entities that had been acting on its behalf should stop doing so.
To allow for the case where an object gets abandoned without IDisposable.Dispose() having been called first, the system allows objects to register a "failsafe" cleanup method called Finalize(). Because for whatever reason, the creators of C# don't like the term Finalize(), the language requires the use of a construct called a "destructor" which does much the same thing. Note that in general, Finalize() will mask rather than solve problems, and can create problems of its own, so it should be used with extreme caution if at all.
A "managed resource" is typically a name given to an object which implements IDisposable and usually, though not always, implements a finalizer.
No, if there are no (managed or unmanaged) resources there is no need for IDisposable either.
Small caveat: some people use IDisposable to clean up eventhandlers or large memory buffers but
you don't seem to use those
it's a questionable pattern anyway.
From my personal experience (confirmed with discussion and other posts here) I would say, that there could be a situations where your object use massive amount of events, or not massive amount but frequent subscriptions and unsubscription from the event which sometimes leads to that the object is not garbage collected. In this case I in Dispose unsubscribe from all events my object subscribed before.
Hope this helps.
IDisposable is also great if you want to benefit the using () {} syntax.
In a WPF project with ViewModels, I wanted to be able to temporarily disable NotifyPropertyChange events from raising. To be sure other developers will re-enable notifications, I wrote a bit of code to be able to write something like:
using (this.PreventNotifyPropertyChanges()) {
// in this block NotifyPropertyChanged won't be called when changing a property value
}
The syntax looks okay and is easily readable. For it to work, there's a bit of code to write. You will need a simple Disposable object and counter.
public class MyViewModel {
private volatile int notifyPropertylocks = 0; // number of locks
protected void NotifyPropertyChanged(string propertyName) {
if (this.notifyPropertylocks == 0) { // check the counter
this.NotifyPropertyChanged(...);
}
}
protected IDisposable PreventNotifyPropertyChanges() {
return new PropertyChangeLock(this);
}
public class PropertyChangeLock : IDisposable {
MyViewModel vm;
// creating this object will increment the lock counter
public PropertyChangeLock(MyViewModel vm) {
this.vm = vm;
this.vm.notifyPropertylocks += 1;
}
// disposing this object will decrement the lock counter
public void Dispose() {
if (this.vm != null) {
this.vm.notifyPropertylocks -= 1;
this.vm = null;
}
}
}
}
There are no resources to dispose here. I wanted a clean code with a kind of try/finally syntax. The using keyword looks better.
is there any benefit to having it : IDisposable?
It doesn't look so in your specific example, however: there is one good reason to implement IDisposable even if you don’t have any IDisposable fields: your descendants might.
This is one of the big architectural problems of IDisposable highlighted in IDisposable: What your mother never told you about resource deallocation. Basically, unless your class is sealed you need to decide whether your descendants are likely to have IDisposable members. And this isn't something you can realistically predict.
So, if your descendants are likely to have IDisposable members, that might be a good reason to implement IDisposable in the base class.
Short answer would be no. However, you can smartly use the nature of the Dispose() executement at the end of the object lifecycle. One have already gave a nice MVC example (Html.BeginForm)
I would like to point out one important aspect of IDisposable and using() {} statement. At the end of the Using statement Dispose() method is automatically called on the using context object (it must have implemented IDisposable interface, of course).
There one more reason that no one mentioned (though it's debateful if it really worth it):
The convension says that if someone uses a class that implement IDisposable, it must call its Dispose method (either explicitly or via the 'using' statement).
But what happens if V1 of a class (in your public API) didn't need IDisposable, but V2 does? Technically it doesn't break backward compatibility to add an interface to a class, but because of that convension, it is! Because old clients of your code won't call its Dispose method and may cause resources to not get freed.
The (almost) only way to avoid it is to implement IDisposable in any case you suspect that you'll need it in the future, to make sure that your clients always call your Dispose method, that some day may be really needed.
The other (and probably better) way is to implemet the lambda pattern mentioned by JaredPar above in the V2 of the API.
While crawling through sources on the web, I've encountered a lot of boiletplate code which looks the following way:
Suppose we have some public class CustomObject: IDisposable, which has a bunch of methods.
Now, each of those methods has default sanity checks:
if (inputBuffer == null)
throw new ArgumentNullException("inputBuffer");
if (outputBuffer == null)
throw new ArgumentNullException("outputBuffer");
if (inputCount < 0)
throw new ArgumentException("inputCount", "< 0");
But (due to the IDisposable interface implementation) the following check is added to each method:
if (disposed)
throw new ObjectDisposedException("MethodName");
Now - is this a common practice? Should I start reengineering my old disposable classes and implementing these checks?
Now - is this a common practice?
Yes, it is recommended. For almost all members. If you class is IDisposable and any method that needs a resource is called after Dispose() then there is a serious logic error in the calling code. Your task is to signal this.
But note that there might be methods (or properties) that do not critically rely on the owned resource(s), they can be considered safe to call after a Dispose(). For instance an IsOpen function/property. It can simply return false, no need for an exception.
But you should not put the IsDisposed check into Dispose() iteself, the guideline is that it should be safe to call Dispose() multiple times.
Should I start reengineering my old disposable classes and implementing these checks?
In general a good idea. Whether it is worth the effort is up to you.
It depends upon your usage, if in doubt it doesn't hurt to add it.
For a class intended to be used by other programs (e.g., libraries and frameworks) I would always perform this check and throw the correct exception as this will aid other applications in diagnosing errors and makes the class more robust.
For internal classes only intended to be consumed by my application you can skip the check if the error will surface quickly when calling the methods. E.g. if every method in the class used a stream, and that stream was disposed or set to null it would result in an exception pretty quickly.
If the internal class has methods that won't error though, I will always use an explicit check as I don't want a situation where some of the methods still work after the object has been disposed (except for methods that explicitly allow it such as IsDisposed).
Having the explicit check does have the advantage of explicitly documenting which methods are allowed to be called after the object has been disposed. More so if you add a comment at the top of methods that do not call GuardDisposed to state that it is allowed, then any method that doesn't start with GuardDisposed or a comment can be regarded as suspect.
To actually implement the check I prefer to move it to a separate method and use it like an assertion, e.g.
public class Foo
{
private bool disposed;
public void DoSomething ()
{
GuardDisposed ();
}
protected void GuardDisposed ()
{
if (disposed)
throw new ObjectDisposedException (GetType ().Name);
}
}
That code you put inside Dispose() (usually) method in order to be sure that it's not called esplicitly (and/or) not esplicitly more then one time on a single instance.
They use it in case when you do in that method something that can be executed one time (DeleteFile, CloseTransaction...) and any other operation you may think of, that is shouldn't executed twice in your app domain.
So if this is a common practice: I would say, it depends on your app requirements.
I have a class hierarchy, each member of which may create IDisposable objects.
I added a List<IDisposable> property to the base class in this hierarchy, to which I add any disposable objects on creation. The root Dispose method iterates through this list and calls Dispose for each item in its list and clears the list. In the application, I explicitly call the top object's Dispose method, causing disposal to cascade through the hierarchy.
This works, but is there a better way? Am I unwittingly duplicating some functionality already present in the framework?
(Note - the objects in question have a lifetime that precludes just wrapping them in a using block or disposing of them in the same methodwhere they are created.)
Edit
Just for clarification - I'm only keeping those objects around that need to be kept. Some are disposed of in the same method where they are created, but many are used in such a way that this isn't possible.
No that is correct. IDisposable is designed to free up unmanaged resources and should be called as soon as possible after you have finished with the instance. It's a common misconception that this is unnecessary, or that the finailizer will do this automatically when the object is garbage collected. It does not.
The correct pattern for IDisposable is here, and included below for quick reference.
public class Resource : IDisposable
{
// Dispose() calls Dispose(true)
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// NOTE: Leave out the finalizer altogether if this class doesn't
// own unmanaged resources itself, but leave the other methods
// exactly as they are.
~Resource()
{
// Finalizer calls Dispose(false)
Dispose(false);
}
// The bulk of the clean-up code is implemented in Dispose(bool)
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// free managed resources
}
// free native resources here if there are any
}
}
So long as you implement the disposable pattern correctly (as described here), this method is fine.
As far as I know, only using statements have special support for IDisposable - there isn't anything in the framework that replicates what you are doing.
If you're talking about arbitrary IDisposable objects, I don't believe it exists.
The System.ComponentModel.Container class implements cascading Dispose, but requires the elements to implement IComponent. If you control your IDisposable objects you could make them implement IComponent - it only requires implementing a single property Site that can return null.
Sounds like a situation where the visitor pattern could be appropriate. Although I never understand the claim that it extends your classes and leaves them unchanged, because I only know examples where classes should have an AcceptVisitor method or the like. BTW, it's not a pattern I like because it is complex and tends to clutter code.
If one object will create many other IDisposable objects and maintain ownership of them throughout its existence, the pattern you describe can be a good one. It may be enhanced by having your class implement method "T RegDispos<T>(T thing) where T:IDisposable;" which will add a disposable to the list and return it. One can thus take care of the creation and cleanup of a resource in the same statement, by replacing a statement like "someField = someDisposType.CreateThing();" with "someField = RegDispos(someDisposType.CreateThing());".
If your class doesn't expose a public constructor (requires outsiders use factory methods), and if you're either using vb.net or are willing to use thread-static fields, you can even combine initialization and cleanup with declaration (e.g. "var someField = RegDispos(someDisposType.CreateThing());"). For this to be safe, the constructor must be invoked within a try/catch or try/finally block that can call Dispose on created sub-objects if construction fails. Because field initializers in C# don't have access to constructor parameters (a weakness in the language, IMHO) the only way to implement such a pattern is to have a factory method create the list and put it into a thread-static variable which can then be read by a static RegDispos method.
Lets say I have a class that associates itself with another class. It would look something like the following:
public class DisposableClassOne : IDisposable
{
private class mDisposableClassTwo;
public DisplosableClassOne(DisposableClassTwo dcTwoInjected)
{
mDisposableClassTwo = dcTwoInjected;
}
public void Dispose()
{
// Should I dispose here? or make caller dispose of dcTwoInjected
//mDisposableClassTwo.Dispose();
}
}
Should I call the Dispose method of mDisposableClassTwo or should I make the caller handle it like this?
using(DisposableClassTwo dcTwoInjected = new DisposableClassTwo())
using(DisposableClassOne dcOne = new DisposableClassOne(dcTwoInjected))
{
// do stuff with dcOne
}
I'm thinking making the caller handle it is the best way to go, but I think by putting the call in the Dispose method it guarantees that it will get called. Is there a better way to handle this?
If the class you are creating logically owns(1) the constructor injected resource then it should dispose of it internally. If it does not own the resource, then it should do nothing, and rely on the consumer to decide when it should be disposed.
If your class owns a reference to an unmanaged resource, you may also need to implement a finalizer (destructor) since there is no guarantee that anyone will ever call your Dispose method at all.
In general, you want to avoid cases where the caller must decide when they should dispose of an object passed to the constructor of a class. It's possible for the caller to dispose of the resource prematurely (or hold on to it longer than necessary). This is not always an easy thing to achieve in certain designs ... sadly, the Disposable Object pattern doesn't always compose cleanly with itself.
(1) By ownership I mean that your class controls the lifetime of the resource which it is passed and no other code holds a reference to it. If any other code (whose lifetime is not tied to the lifetime of your class) holds a reference to the resource and will use it independently, then you are not the owner of that resource.
I think it is a life-time decision you have to make in your design.
Is DisposableClassOne Disposable BECAUSE it references a DisposableClassTwo?
And,
Does a DisposableClassTwo have a lifetime independent of DisposableClassOne?
To me, the answers to these two questions varies in each class design. The StreamReader/Writer is a great example of the first question being 'yes' and the second 'no' - no one would expect to use a Stream inside a StreamReader once the Reader is done with it, so Reader disposes it.
But what if DisposableClassTwo was some other resource - maybe a file refernece you passed to several classes in turn to 'do something to'. In that case, you don't want it disposed until you're ready and DisposableClassOne might be long gone by then.
The standard I'm familiar with is to use the Disposable pattern. Have a virtual Dispose(bool disposing) method. The Dispose() method calls Dispose(true) and the finalizer calls Dispose(false).
Then, in the main disposal method:
if (disposing)
{
// Dispose of the referenced object, as well.
}
StreamWriter & StreamReader follow this pattern. If you explicitely call Dispose(), they also dispose the underlying Stream. If you let the finalizer do your cleanup, they leave it alone.
Alternatively, you could add a property: DisposeChild, if true, dispose the child object, if not, leave it alone.
I also agree with rcravens. Under almost all circumstances, an object should be disposed within the same scope where it was instantiated.
To use IDisposable objects properly, one must follow the principle "Would the last one out please turn off the lights". There are a few nice scenarios, and an icky one:
The creator of an object gives it to another object (the "recipient") but the creator of the first object controls the recipient's lifetime, and can know when the recipient will no longer need the passed object. In that case, the creator of the original object takes care of Dispose.
The creator of an object gives it to the recipient, and the recipient knows that nobody else will use the object once it's been handed over. In that case, the recipient will call Dispose when it's done with the object.
An object recipient may sometimes be used in ways that match #1 and sometimes in ways that match #2, but the supplier of the object will know when it's given which situation applies. This situation may be handled by telling the recipient whether or not the recipient should Dispose of the object it is given.
The supplier and recipient will both want to use the object, but may have no idea which is going to outlive the other. This is the toughest situation.
I tend to like the approach suggested in #3. Sometimes situation #4 applies, though. One way of handling that is for the recipient of the object to fire an event when it's done with the object. That event can Interlocked.Decrement a counter indicating how many objects are still using the passed object. Once that counter hits zero, the object may be deleted.
It is better not to dispose any external references, those would be disposed automatically by the caller itself.
See this thread, in which it is suggested that only member variable needs to be disposed:
Finalize/Dispose pattern in C#
The concept of "cleanup by owner" is far too common to be ignored. Ownership must be more than just coincidence.
If you want software that is easier to maintain, avoid side effects that may be incorrectly interpreted. The Stream vs StreamReader example is a great one... both are IDisposable, and as the caller, I'm making both, so in no way should I ever give myself a pass at disposing either of them. Doing so would violate the abstraction, tying my calling code's knowledge to the particulars of the stream class' implementation (which could change over time, academically).
The easiest answer is to have the two usings(), even if you then go and make (and document!) that the second IDisposable will dispose of the first.
I am currently working on fixing a c# codebase which does not have a good pattern of Dispose usage.
It is a large codebase, it is a resource demanding codebase and it uses many custom unmanaged c++ libraries at the low level.
I have a good understanding of the dispose pattern. I have spent some time understanding what I believe to be the gold standard article on the issue: Joe Duffy's dispose article
In an attempt to minimise code duplication, we have been considering some dispose helper classes, and so my question:
If a base class implements a standard Dispose pattern should it allow its disposed flag to be shared ie. marked as protected?
To clarify I mean should there only be a single boolean state within an inheritance heirarchy that defines whether an object instance has been disposed or should there be a private boolean at each step of the inheritance ladder?
The examples in MSDN and at the above link set a flag at each level, but never explain the reasoning behind it. I am in two minds on the issue, what are your thoughts and reasons?
I would say no it should not share the flag. Sharing the flag creates opportunities for failure which better encapsulation could prevent.
For instance, consider the scenario where you have a readonly Disposed property on the base most class. The backing field is only set to true in the Dispose(disposing) method on the base class. This means that the property Disposed can only ever return true if the base class Dispose is called (barring evil reflection of course). This allows the base class to provide an enforceable contract.
Now consider the opposite, where there is a protected setter. Any class can now arbitrarily set the Disposed property to true without disposing anything. This creates an opportunity for Dispose to return true when nothing is disposed.
I would choose the first option because it provides the most enforceable contract.
I would recommend having a Disposed property on the base class with a public getter and a protected setter.
In the case you have methods that should do something different when the class has been disposed, for example throwing an exception, I would create a protected only getter property for the base class that reads the private field on the base class. This way you allow any inheritor to know if he's able to perform an operation.
Then, for knowing if a class has already been disposed into its own dispose method (for example: to avoid releasing resources twice), I think that having a private flag is better for clarity and maintenance.
In addition to JaredPar's answer, I'd add that it is not always necessary for there to be a _disposed flag. Very often, the other "resource-related" fields of the object naturally provide a way to represent the disposed state.
For example, an external COM object that needs to be Shutdown before it is discarded would be represented by a reference to the COM object, and so the relevant part of Dispose would be:
if (_comObject != null)
{
_comObject.Shutdown();
_comObject = null;
}
This can safely be run multiple times without calling Shutdown more than once, as is required. Other methods that attempt to use _comObject after Dispose will get a NullReferenceException, or ideally those methods would check the _comObject field and throw ObjectDisposedException.
I find this is more often true than not - having frequently implemented IDisposable, I can't recall ever needing a separate _disposed field. Introducing one would increase the degrees of freedom (increase the number of ways for me to screw it up).
So this is unlikely to be that useful for derived classes even if it was a safe idea (which it isn't, as JaredPar explains).