Using the ComReleaser to manage the lifetime of cursors in .NET

Geodatabase cursors should always be explicitly destroyed in a runtime environment that uses garbage collection. The rule of thumb is to always release a COM object as soon as the application is done using the reference. This is especially important with geodatabase cursors because failing to dispose of cursors can put locks on system and DBMS resources; a common symptom of this is having a table remain locked for an indeterminate amount of time after you’ve finished iterating through its rows with a search cursor.

This article in the .NET SDK is a great read for developers using the geodatabase API – it discusses the importance of releasing COM objects (and cursors specifically) as well as a few different approaches. Many .NET developers who have worked with COM interop will be familiar with the static method Marshal.ReleaseComObject, but there’s also a section about an ADF class called the ComReleaser that is really handy when working with cursors.

Here’s an example of using the ComReleaser to ensure a cursor is properly disposed of:

using (ComReleaser comReleaser = new ComReleaser())


      // Instantiate a cursor and manage its lifetime with the ComReleaser.

      IFeatureCursor featureCursor = featureClass.Search(null, true);



      // Iterate through the features.

      IFeature feature = null;

      while ((feature = featureCursor.NextFeature()) != null)


            // Do something.



Regardless of how the code leaves this using block – whether a value is returned, an exception is thrown, or it gracefully exits – the cursor will have its reference count properly decremented.

This entry was posted in Geodata and tagged , , , . Bookmark the permalink.

Leave a Reply


  1. harley84 says:

    Can ComReleaser be used to manage more than one cursor/COM object?

    Thanks in advance

  2. mackayj80 says:

    Hi Harley,

    You can manage the lifetime of as many COM objects as you want with a single ComReleaser. If you have two cursors with a similar lifespan – for example a search cursor reading one dataset and an insert cursor inserting values into another – it’s probably best just to have a single using block.