I have an object, which contains a collection of other objects. I want to dispose of them all by calling the dispose method on the base object. The dispose method of the collection will clear the collection, but it does not dispose of the individual objects it contains. So I need my base object to loop through and dispose of each child object. The last detail is that I want to make sure that the collection is disposed of before the individual objects it contains.
I am thinking I can get this behavior by using Dispatcher.BeginInvoke and a low priority. First passing it the dispose call for the collection and then looping through and disposing each individual item. (pseudo) code looking something like this:
class Foo
{
FooCollection Children;
void Dispose()
{
//unsubscribe from data model events
CurrentDispatcher.BeginInvoke(Children.Dispose, ApplicationIdle, null);
foreach (Foo Child in Children)
{
CurrentDispatcher.BeginInvoke(Child.Dispose, ApplicationIdle, null);
}
}
}
class FooCollection
{
void Dispose()
{
//unsubscribe from data model events
this.Clear();
}
}
Am I on the right track? Or am I just setting myself up with a race condition? i.e. is it possible that the Dispatcher could get around to calling dispose on the collection before the foreach finishes queing up the dispose calls for the children? Is there a better way to get the desired behavior?
It is probably worth noting that each of these classes exposes events, and hooks handlers into other objects. My primary goal is to make sure all of the handlers get cleaned up gracefully when dispose is called.
EDIT (8/24): The instances of these classes subscribe to events from objects which generally persist for the life of the application. Because of this, the persistent object maintains a reference to each of these instances. I am trying to make sure that each instance unsubscribes from the persistent object's events when the instance is no longer needed.
EDIT 2 (8/30): This is part of a view model, which represents a data hierarchy retrieved from a web service. The cost of retrieving the data from the web service is high, so the actual data objects returned are cached, generally for the life of the application. The data objects implement ICollectionChanged and IPropertyChanged, the view model objects in question subscribe to these events. The nature of the application is such that user actions will likely cause the view model to be discarded and recreated several times during a session. The nature of the data is such that there will commonly be several thousand nodes in the hierarchy which have to be represented in the model. The primary concerns, as they relate to this question, are:
1) Making sure that the discarded view model unsubscribes from the events of the underlying data model
2) Making sure it is done in such a way that looping through the full hierarchy of the discarded view model does not noticeably impact the user in working with the new instance of the view model.
I have updated the code example to more accurately represent the situation. So the question remains. Will this code give me the expected result in that the collection, and then all of its children, will be queued up for disposal before any object actually gets disposed, and then some time later the thread will start disposing them when it has idle time? Or is it going to create a race condition where the collection could possibly be disposed of before I have finished looping through it?
Most posters have focused on the fact that the collection gets cleared, in all honesty clearing the collection is probably unnecessary, but it is a bit of a habit, and I consider it to be good housekeeping.