Hi,
I've started looking into the Undo/Redo framework, and have a scenario I currently fail to find a quick solution to in the documentation.
The issue is that my undo transactions will involve objects that need some cleanup before being garbage collected. This may include detaching event handlers and/or deleting some files on disk. If I e.g. delete such objects from my object graph within an undo transaction I obviously can't clean them up immediately, since the objects may be brought back during a redo. What I need is a way to clean up these objects when they fall off the UndoHistory and are gueranteed to be gone forever.
What is the recommended pattern to solve this issue ?
Regards,Leif
There is (at least currently) no notification made to an undounit or otherwise when an item is removed from the history. Typically if one is holding unmanaged resources then one might implement a finalizer (and IDisposable) and handle releasing those unmanaged resources in there. Perhaps the managed object you are referencing (e.g. a FileStream or more accurately the SafeFileHandle of a FileStream) would automatically handle that when it is finalized. Or perhaps you manage some weak dictionary of references to your object and periodically check to see if that weak reference is released. If so then you would do your clean up. Typically I would think that file deletion is not something that is deferred. I mean if the user closes the app you would still need to do that clean up before the app shuts down or worst if the app were to be forceably shut down or crash then those deletions would not have actually occurred.
With regards to event handlers it would depend upon the situation. If the object is in the undo history because it was removed from a collection for example then typically I would think you would want to disconnect that object and unhook any events. Should that object instance be re-added to the collection then you would reconnect it and hook whatever events you needed to. If they are hooking static events and need to stay hooked in then perhaps you would use one of the weak event patterns to ensure the object is not rooted by that static event handler.
thanks for the answer. We really would like a deterministic way to delete our files, and not rely on e.g. finalizers. We also can't wait until the application is finished to do such a cleanup, since the files in question are very big.
Just to describe our scenario a bit. We have an application that is able to process huge amounts of Ground Penetrating Radar (GPR) data. The output of each processing job may result in physical result files with sizes of several hundred megabytes each. We would like to give the user an option to revert individual processing jobs (or batches of such jobs) which makes these jobs end up in the undo list. This may populate the undo list with processing job objects that may be backed by hundreds of megabytes of disk space that the application is otherwise done with unless the user selects to undo the operation(s). To not actually make the user run out of disk space it is vital for us to know when the last reference to these files (in this case the undo history) is gone, so that we can delete them immediately.
I'm sure we can find a workaround for this that may work, but I suspect that this will include code that add unneeded complexity compared to a simple cleanup callback from the Undo framework.