Application Developers Tuning Tip: Keeping Datasets Open

Opening a dataset such as a table or a feature class from a geodatabase can be an expensive operation. With this in mind, application developers should try to minimize the number of times they open datasets by following these patterns:

Keep datasets from going out of scope: If a dataset is being opened in a method that gets called frequently, consider keeping a reference to the dataset outside of the method to keep it from going out of scope and forcing the application to reopen it each time the method is called.

The code below shows an example of how this might look before and after:

Of course, this will apply a shared schema lock to the feature class so it may not be appropriate for all applications.

Open related classes when notification is used: Whenever an application is editing a dataset and that dataset participates in a relationship class with notification, it’s related dataset should also be kept open. Consider a Parcels-Owners relationship class that has forward notification enabled; whenever a parcel is created, deleted or modified, a message is sent to the Owners class. If the Owners class is not open it will be opened by the system. The geodatabase must do this because a response to the message may occur (i.e. deleting an owner in response to the deletion of a parcel, for composite relationships). After a class is opened by the geodatabase it will be closed.

Application developers can prevent this kind of performance hit by simply opening the related class at the same scope as the class being edited. How much this improves performance depends on many factors, but a ten-fold increase is not atypical, and fifty-fold increases have occurred.

3 Comments

Corithsays:

Perhaps it would be useful to add to this post and describe how you can use the IDisposable interface to ensure you Marshal the class scoped FeatureClass? Just having it as a class variable means that it’s not getting cleaned up until the GarbageCollector comes around and even then it’s not decrementing the reference count. IDisposable is a great way to ensure this happens as long as the user of the class wraps it in a using clause or calls Dispose() manually.

That’s a good point; the type of application I had in mind in the first section would be one where the lifespan of the application roughly corresponds to the lifespan of the class, but if the application outlives the class, implementing IDisposable on the class would definitely be a good practice.

A related topic is the use of the ComReleaser (from the .NET ADF assembly) to ensure the deterministic release of datasets, although this is more appropriate when the datasets are scoped to a method rather than instance variables. We’ve got an earlier post about cursors that can be applied to tables and feature classes, as well:

I’ve seen issues taking this approach especially if you’re using Engine and you switch between map and the scene or globe. You must make sure to save the workspace or some of your data may not appear or you’ll get errors.