2

I have a recycling feature cursor that is used to fetch a single row. Is it my responsibility to release that returned feature, or will it be cleaned up by the cursor as it would be if I consumed the entire cursor?

public object GetFirstValue(IFeatureClass featureClass, string field)
{
    IFeatureCursor cursor;
    IFeature feature;
    try
    {
        cursor = featureClass.Search(null, true);
        feature = cursor.NextFeature();
        return feature.get_Value(feature.Fields.FindField(field));
    }
    finally
    {
        if(cursor != null) Marshal.ReleaseComObject(cursor);
        //do I need to release the feature here?
    }
}
2
  • I suppose creating a recycling-cursor that should only return one single element makes no sense at all, as the purpose of recycling to reuse the same Com-object if more than one row is returned, which isn´t the case here. So you can also use a non-recycling cursor here which will give you the answer. Commented Jan 20, 2017 at 8:56
  • Yes, I was thinking more along the lines of stopping part way through iteration of a large number of features, so you've had the benefit of a recycling cursor but the final row hasn't been disposed. See @nmktronas answer and my extension below - the feature does need to be released even after full iteration to return all memory, and especially for shapefiles which remain locked until this (or GC) occurs. Commented Jan 23, 2017 at 7:36

3 Answers 3

1

You should call Marshal.ReleaseComObject in the finally block before releasing of the cursor if you want to release unmanaged memory allocated for the feature RCW. If you don't call this then the GC will take care of it when RCW finalizer is invoked.

1
  • So in the event that I iterate the first 3 features of a cursor that would return more than 3, so NextFeature() has not yet returned null, is it still my responsibility to release the feature? Assuming that I don't want any more features from the cursor, of course. And thus that the only time it isn't my responsibility is when I iterate to the end of the cursor, until NextFeature() returns null? Commented Mar 25, 2015 at 11:50
0

As I've always understood it as your feature object is local to the GetFirstValue function it should be destroyed and memory released when the code is returned to the calling code. But I have found COM objects don't always behave as expected and in this case I can't see a problem with you explicitly setting it to Nothing.

But how about this as an alternative? Looking at your code it appears you have no search criteria and thus return the first feature. I'm guessing you are passing in a FeatureClass of one row? Why not simply use the GetFeature method on IFeatureClass an do away with the cursor?

2
  • Yes, the feature should be cleaned up by the garbage collector, which will release the underlying COM object, either by exiting the method or by setting the reference to null. What I'd like to know is if there's any need to release it explicitly (by calling Marshal.ReleaseComObject) due to limited resources (such as database connections). Commented Dec 22, 2014 at 9:15
  • Doesn't IFeatureClass.GetFeature() return a IFeatureCursor object?
    – Barbarossa
    Commented Mar 8, 2017 at 17:02
0

An extension to Nmktronas' answer:

At least with Shapefiles, features hold a lock on the feature class they're from, so it is necessary to release them in order to e.g. delete the workspace (at least using System.IO.Directory.Delete for a Shapefile folder). This is true even with a recycling cursor that has been fully iterated - the recycled feature must be released either by your code or by the GC before the lock file will be removed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.