While everyone has mentioned (unmanaged) resources, i have another thing to add: i use it when i need to eliminate event handler hookups that would otherwise prevent a class from going out of scope and being garbage collected.
As an example, i have a service which gets injected in to a child view, that child view will subscribe to various async finished type events on the service. The owner of that child view has no idea what the concrete type is, it simply has it as an interface. The serice may go out of scope at some arbitrary point in the future, and i don't want it hanging around not being gc'ed. Upon getting rid of that child view, the owner will call Dispose on it to give it the chance to unhook any event handlers. Here is a slightly contrived (and very pseudo code) example, note how the interface for the child view also implements IDisposable.
public class OwnerView {
public OwnerView() {
_childView = new ChildView(myServiceReference);
}
public void CloseChildView() {
if (childView != null) {
_childView.Close();
_childView.Dispose();
}
_childView = null;
}
private IChildView _childView;
}
public class ChildView : IChildView {
public ChildView(MyService serviceRef) {
_serviceRef = serviceRef;
_serviceRef.GetSettingsAsyncFinished += new EventHandler(someEventHandler);
}
public void IDisposable.Dispose() {
_serviceRef -= someEventHandler;
}
private MyService _serviceRef;
}
public interface IChildView : IDisposable {
void DoSomething();
... etc ...
}
There are far more authorative comments about this from others on SO, like this and this. You may also want to check out this codeproject article.