Select to view content in your preferred language

Any way to check whether a COM ArcObjects object is already released?

1887
12
Jump to solution
08-02-2012 10:02 AM
SuiHuang
Frequent Contributor
Hi Everybody:

    I found that after an ArcObject COM object is release, some operations such as checking interface cannot be performed on it and otherwise it will throw exception.
    Is there any way for me to detect whether the object has already been release? I am trying not to use the TRY-CATCH pair to handle this logic...
    Thank you.


**************** Released twice by my utility function ******
    IPoint obj = new PointClass();
    ReleaseObjects(obj);
    ReleaseObjects(obj);


**************** Utility functions *********
        public void ReleaseObjects(params object[] comObjList)
        {
            foreach (object obj in comObjList)
            {
                if (obj != null)
                {
                    if (obj is System.Collections.IEnumerable)
                    {
                        ReleaseComs(obj as IEnumerable);
                    }
                    else
                    {
                        Marshal.ReleaseComObject(obj);
                    }
                }
            }
        }

        private void ReleaseComs(IEnumerable Objects)
        {
            foreach (object obj in Objects)
            {
                if (obj != null)
                {
                    if (obj is IEnumerable)
                    {
                        ReleaseComs(obj as IEnumerable);
                    }
                    else
                    {
                        Marshal.ReleaseComObject(obj);
                    }
                }
            }
        }
0 Kudos
1 Solution

Accepted Solutions
AlexanderGray
Honored Contributor
Using releaseComObject is necessary in .NET code because some objects' reference count don't decrement when they go out of scope and don't get collected in GarbageCollection.  This is a problem for cursor because you can exceed the number of open cursors you are allowed to have.  It is also a problem with featureclasses and workspaces and other geodatabase objects that maintain locks until they are explicitly release.
If you set your variable to null after calling the release you should be able to test to see if the variable is null and avoid calling it a second time.  Aside from that I would only suggest keeping a tighter control on the variables to avoid release being called a an object separated from the RCW.

View solution in original post

0 Kudos
12 Replies
LeoDonahue
Deactivated User
Is there any way for me to detect whether the object has already been release?

What are you trying to do?

If .NET Garbage collection works the same way as it does in Java, then when an object variable goes out scope, or you set it to null or you assign it another reference, then the object becomes eligible for garbage collection, but you don't know when exactly that happens in the run time environment.

Personally, I don't think you should care whether it has been released or not after the fact, because you would be the person who is releasing it intentionally or via the the way you are structuring your code.

Maybe this link describes what you want to do:  http://edndoc.esri.com/arcobjects/9.2/NET/fe9f7423-2100-4c70-8bd6-f4f16d5ce8c0.htm#ReleaseComObject
0 Kudos
AlexanderGray
Honored Contributor
Using releaseComObject is necessary in .NET code because some objects' reference count don't decrement when they go out of scope and don't get collected in GarbageCollection.  This is a problem for cursor because you can exceed the number of open cursors you are allowed to have.  It is also a problem with featureclasses and workspaces and other geodatabase objects that maintain locks until they are explicitly release.
If you set your variable to null after calling the release you should be able to test to see if the variable is null and avoid calling it a second time.  Aside from that I would only suggest keeping a tighter control on the variables to avoid release being called a an object separated from the RCW.
0 Kudos
SuiHuang
Frequent Contributor
Personally, I don't think you should care whether it has been released or not after the fact, because you would be the person who is releasing it intentionally or via the the way you are structuring your code.
[/url]

Just because I am releasing it intentionally, I need to care. Because the current way I am structuring the code doesn't support double releasing. Releasing a released COM object will throw exception.
0 Kudos
SuiHuang
Frequent Contributor
Using releaseComObject is necessary in .NET code because some objects' reference count don't decrement when they go out of scope and don't get collected in GarbageCollection.  This is a problem for cursor because you can exceed the number of open cursors you are allowed to have.  It is also a problem with featureclasses and workspaces and other geodatabase objects that maintain locks until they are explicitly release.
If you set your variable to null after calling the release you should be able to test to see if the variable is null and avoid calling it a second time.  Aside from that I would only suggest keeping a tighter control on the variables to avoid release being called a an object separated from the RCW.


Thank you! Seems then assigning null value and avoid calling a second time are the only available ways to go.
0 Kudos
LeoDonahue
Deactivated User
Just because I am releasing it intentionally, I need to care. Because the current way I am structuring the code doesn't support double releasing. Releasing a released COM object will throw exception.

If you, as the programmer, decided to release an object reference, why do you want to know if it has been released or not?  Create a new object.
0 Kudos
LeoDonahue
Deactivated User

If you set your variable to null after calling the release you should be able to test to see if the variable is null and avoid calling it a second time.

Not to nitpick, but if you set a reference to null *after* you have explicitly released it, what other value do you expect it to have when you test it for null?

Is Sui trying to call a method on that Object just before it is actually killed off?  Not a good idea.
0 Kudos
SuiHuang
Frequent Contributor
Not to nitpick, but if you set a reference to null *after* you have explicitly released it, what other value to expect it to have when you test it for null?

Is Sui trying to call a method on that Object just before it is actually killed off?  Not a good idea.


Here is a sample senario:
*******************************
List<IFeature> fList = ...
int i = ...
IFeature f = null;
if (...)
{
    f = fList
}
else if
{
    f=...
}

//release fList
//release f
*******************************

In the above case if I release everything in fList without assigning null and f=fList was executed, then I will get exception.
0 Kudos
LeoDonahue
Deactivated User
If you are releasing fList and f at the end of your procedure/function/method - whatever, how are you getting an exception?

Also, telling us what kind of exception you're getting would help.  Is it NullPointerException?  AutomationException?  something else?
0 Kudos
SuiHuang
Frequent Contributor
If you are releasing fList and f at the end of your procedure/function/method - whatever, how are you getting an exception?

Also, telling us what kind of exception you're getting would help.  Is it NullPointerException?  AutomationException?  something else?


Hi Idonahue:

    The exception message tells "COM object that has been separated from its underlying RCW cannot be used."
    Any idea? Thank you!
0 Kudos