(very newbie questions)
i may be misunderstanding this but on MSDN i believe it says that it is good practice to implement the Dispose destructor in every class you write. should i (do you) really implement the IDisposable interface with every class i write?
also, is the proper syntax for implementing an interface to put the "Implements" keyword on the line after the "class" declaration? i put it on the same line as "class" and I got an error.
one more?: when coding the method implemented by the interface, is it mandatory to follow this syntax, as an example:
Public Sub Dispose() Implements IDisposable.Dispose
what i'm curious about in the above code, is if i need to declare the implemented method as
"Implements System.IDisposable.Dispose"
You should only implement IDisposable if your class holds instances of other classes that implement IDisposable, or if it holds native resources.
For more information, see this article.
No you should not. Only implement IDisposable if you are using unmanaged resources directly or have members that implement IDisposable and want to make sure their dispose method gets called when the dispose method gets called on your class.
Many actions a computer might perform create the need for a counter-balancing "cleanup" action. For example, the act of opening a file creates a need to close it. The act of placing a call with a modem creates the need to disconnect it. Performing an action without performing the required counter-balancing cleanup may sometimes be harmless, but may sometimes have severe consequences in the computer or in the real world (failing to close a file before a user ejects the media may cause file corruption and data loss; failing to terminate a modem connection may cost someone many dollars in excess phone charges).
The purpose of IDisposable is provide a means by which well-behaved programs can make sure that any cleanup actions that need to be performed actually get done. Any routine which performs an operation that must be counter-balanced by cleanup should keep the information and impetus necessary to perform such cleanup until such time as it has been performed; if the routine can't perform such cleanup before returning to the caller, it should either (1) provide the information to the caller, and be documented as requiring the caller to use that information to perform the cleanup, or (2) keep the necessary information in one or more fields, and implement IDisposable; when IDisposable.Dispose is called, the object should use the saved information to perform the cleanup.
Note that IDisposable only works cleanly if any object that requests the creation of an IDisposable object accepts and honors the responsibility of making sure that the object's IDisposable.Dispose method will be called sometime. The system does provide a "backup" means, called finalization, which objects can use to ensure that they get a chance to perform their cleanup. Essentially, an object registers a request with the system that says "Let me know if I've been abandoned". If the system detects that an object has been abandoned, it will try to give the object a chance to perform any necessary cleanup. Note the system may take awhile to notice that an object has been abandoned, and for various reasons the notifications may not always happen. It is almost always much better to call IDisposable.Dispose on objects before they are abandoned, than to rely upon the "last chance" finalization mechanism.
The .Net framework has a garbage collector and for the most part manages allocation and release of memory for you (when creating a new object). However you also need to manage un-managed resources (I also seen being refereed to as native resources). So now the garbage collector is not good enough and you have to manage memory using the IDisposable interface. A good example is creating the DataAccesslayer where you handle database connection and use the IDisposable interface
check this out to see how to implement iDisposable interface:
https://msdn.microsoft.com/en-us/library/498928w2%28v=vs.110%29.aspx
Related
My question is specific to, why and where not to implement IDisposable interface.
If I am not using & consuming any unmanaged resources, still is it good practice to implement IDisposable interface.
What are the advantages or disadvantages if I do it? or is it good practice to implement it?
Please advise.
You implement IDisposable for one of two reasons:
If you have Unmanaged resources to free.
You do this because this is the only way for the GC to know how to free unmanaged resources which otherwise it doesnt know about. This is about WHAT resources to free. This case is actually quite rare - more often than not you access unmanaged resources through existing managed objects. This case requires a full "official recommended" implementation. Generally you should wrap unmanaged resources in their own separate (managed) class that does the IDisposable implimentation (rather than including unmanaged resources in other larger objects).
If your class contains objects that impliment IDisposable.
You do this not because the objects won't get free if you don't (they will) but because you want to be able to control WHEN those resources are freed. Having a dispose impliementation that disposes disposable members of a class means that consumer can apply a using statement to easily control WHEN resources are freed. In pratice more often than not this is the main reason for implementing IDisposable. Note that if your class is sealed you can get away with a mimimal IDisposable implementation here - I.e just Dispose - there is no need for the full blown "official recommended' implimenation.
It follows that if neither of these cases applies then no need to implement.
If a class implements IDisposable, that will generally impart to any code which creates instances of that class a responsibility to ensure that Dispose gets called on that instance before it is abandoned; it may fulfill this responsibility either by calling Dispose on the object itself when it is no longer needed, or by making sure that some other object that receives a reference accepts "ownership" and responsibility for it. In the majority of cases, when code is written correctly, each IDisposable object upon which Dispose has not yet been called, will at every point in time, have exactly one other entity (object or execution scope) which "owns" it. During the lifetime of the IDisposable object, ownership may get passed among different entities, but when one object receives ownership the former object should relinquish it.
In many cases, objects will be used in such a fashion that tracking ownership is not difficult. Generally, any object whose state is ever going to be modified should have exactly one owner and that owner will know when the object is no longer needed. Additionally, because modification of the owned object's state would constitute modification of the owner's state, the owner itself should have a single owner. In such cases, requiring the owner to call Dispose will not pose any difficulty (the owner's owner should call Dispose on it). There is, however, a 'gotcha' with this principle: it's possible for an object to create an instance of a mutable class but never mutate it nor allow anyone else to do so. If the mutable class in question simply holds values and does not implement IDisposable, objects which hold references to the things that will never actually mutate need not concern themselves with ownership. This can allow some major simplifications, since it will be possible for many objects to hold references to the non-changing object and not have to worry about which of them will use it last. If, however, the mutable class in question implements IDisposable, such simplifications are no longer possible.
As the title, When a form disposed, are all form data and datasets also disposed?
Example:
Dim C As New Commands
C.ShowDialog
C.Disopse()
So C form contains datasets and oledbconnections and more objects that were not disposed . If not, what is the best method to free memory and release all resources?
As with other .NET objects, you cannot guarantee datasets will be disposed when the form is disposed. This is because .NET constantly monitors whether or not there are active pointers to the objects in memory. If no links were found, it frees up memory allocated to the object. Such process is called garbage collection - a feature of CLR.
Problem is that you can have a variable that points to the same data set, on another form, class, and even in another project. You can spawn as many of those variables as you want. As a developer, you must work out a strategy to control who consumes your objects and how. Otherwise you will never know if at any given moment a particular dataset was actually disposed.
Using clause helps control disposal of objects, but it's not the ultimate solution. You can still get in trouble if you don't know what you are doing. And sometimes you would need to pass undisposed connection objects to other functions on purpose, for more granular control over data processing.
A form's .Dispose() method is there to handle the otherwise-unmanaged GDI resources used by the form. Since that method doesn't know anything else about what you might have added, you can't be sure that items such as datasets are disposed as well.
The best you can hope for is that since Dispose()-ing a form is also highly indicative that the form is about to become eligible for garbage collection, your other resources are also likely about to become eligible for garbage collection. If the Dispose() and finalizer patterns for those types was implemented correctly, then it is highly likely that your other items will be disposed soon. Just how soon is impossible to say... that's why the dispose pattern exists: for those times when you need to sure an unmanaged resource is cleaned up right away.
The way I would recommend freeing any additional resources is to override the normal Windows Forms Dispose() method. Your new implementation of the Dispose() method will call the base implementation using the MyBase keyword, and also call Dispose() for any IDisposable members of your form. This way, the form will still work correctly as part of a Using block.
I'm writing a managed wrapper around DirectSound. (It's a simple partial wrapper that solves my specific problem and nothing more. Don't tell me about NAudio or whatever.) Should a managed class that wraps IDirectSound8 be IDisposable and why? Same question about IDirectSoundBuffer8.
Technically: yes. Practically: no. IDirectSound8 is a COM interface, they are very conveniently wrapped in .NET with a interop library. An RCW. That RCW manages the reference counts on the underlying COM coclass object. An RCW does not implement IDisposable, even though it very much hangs on to an unmanaged resource.
The reason it doesn't is because it is almost impossible to implement IDisposable correctly. A COM coclass implements multiple interfaces, creating one adds to the reference count. You would have to be 100% sure that all of those interface pointers are no longer in use before a dispose would be safe. That's very hard to do, those pointers get created in unexpected ways. Like using an indexed property of one of the interfaces, the intermediate interface pointer is never visible in your code.
This is not a real problem, the garbage collector takes care of the reference counts, the finalizer gets the job done. It is just that it takes a bit longer for the object to be released. Standard GC behavior. Unfortunately out-of-process COM servers have observable side-effects, programmers tend to get annoyed when the process doesn't disappear from the TaskMgr processes list at the instant their code stops using the interfaces. Many, many "Excel/Word doesn't quit" questions here and at the forums.
If you want to implement it anyway then you can do so by calling Marshal.FinalReleaseComObject() in your Dispose() implementation. Just beware of the significantly increased risk for failure, getting that call wrong produces very hard to diagnose failure. Not quite unlike deleting an object in native code and still having a pointer to it. If it is actually a "heavy" object that must be released instantly then GC.Collect() + GC.WaitForPendingFinalizers() gets the job done too with much less risk of getting it wrong. With side-effects of course.
It's quoted from a report by Bjarne:
Encapsulation – the ability to provide
guarantees that an abstraction is used
only according to its specification –
is crucial to defend abstractions
against corruption.
Can someone explain this?
Thanks
Let's say you have a class with public methods that you must use to perform some action. The specification of the class say that, in order to do this action, you must configure the class in a specific way (call this method, set this property, etc).
The problem with situations like this is that it might not be clear what needs to happen or in what order. So the API for the class is hard to use and confusing for the majority of developers.
With encapsulation, you can "encapsulate" not just the class but the algorithms to use it within a second class. This second class sets up the original one, configures it, and manages its lifetime. It allows you to access the API without needing to know how to use it correctly, as the encapsulating class takes care of that. This is sometimes called the Facade pattern.
Your quote also says "is crucial to defend abstractions against corruption." What this means is that when you abstract some process into a class, different implementations of that process should not require the abstraction to be handled differently.
For example, you might have two implementations of a report writer class. You should be able to treat each of them exactly the same without ever knowing how they are implemented (the meaning of abstraction). However, if one cannot be run in a multithreaded apartment state (MTA), you have to "know", before you use it, that it is time to transition to an STA thread. This magical "knowing" is required by the implementation of the class. This is a "leaky abstraction."
With encapsulation, you could prevent this "leak" by, within the encapsulating class, making the transition to an STA thread within the encapsulation, preventing the abstraction from leaking details of its implementation.
It means that the object grant premission only to certain things it needs to expose, and deny you from using data it doen't want you to use.
The most classic example is properties:
Yout fields will be private (or protected).
If you would like to expose them for read or write, you'll add a getter\setter, accordingly.
Instead of using an interface like this:
public interface IStartable
{
void Start();
void Stop();
}
I usually just make the constructor of an object run the Start() code, and implement IDisposable so that the dispose method runs the Stop() code.
Is it just a matter of style? Or am I missing something important by not having something like IStartable? All I see is extra complexity, because you have to maintain it's started/stopped state.
What are the pros and cons of using start/stop vs using ctor/dispose, especially in the context of an IoC/DI container?
EDIT: Great answers, you've convinced me to use an interface for startable objects. I can't decide who's answer is the best so I'll accept whoever has the most up votes after 24 hours.
The general advantage to using an interface is that they're self-describing and self-advertising. If there's no interface, you don't have a way to ask an object, "can you be started and stopped?" If you do use an interface, by contrast, you can query objects to see which of them will respond to those kinds of messages. Then you can be safely guaranteed that such objects have implemented the functionality encapsulated by the interface.
in general, constructors should produce a properly-initialized object
and nothing more!
It could possibly depend on what, specifically, you mean to be happening when you say Start(). But in general, mixing object initialization with routine execution (especially stateful and/or long-running execution!) violates SoC.
It also leaves a great deal of ambiguity. To a consumer, for a given object how do we know it is "starting" when we invoke the ctor? "For this given object, which implements no contract, I must leave it to hope in the author that it conforms to my expectations"? An interface makes the presence and availability of the action explicit.