We have an VB.Net application that uses a COM automation server. There is an
object leak that we don't know how to solve.
objColl = autoServer.TheCollection
foreach objMember in objColl
.
.
.
System.Runtime.InteropServices.Marshal.ReleaseComObject(objMember)
next
System.Runtime.InteropServices.Marshal.ReleaseComObject(objColl)
The problem is that foreach creates a hidden reference to IEnumerate (if I
remember the name correctly) that we don't how to pass to ReleaseComObject.
That causes leam for all the members in the collection.
Any solution?
Thanks
> We have an VB.Net application that uses a COM automation server. There is
> an object leak that we don't know how to solve.
[quoted text clipped - 11 lines]
> remember the name correctly) that we don't how to pass to
> ReleaseComObject. That causes leam for all the members in the collection.
Are you sure there's a memory leak? Generally speaking ReleaseComObject does
not have to be called manually, since the framework will take care of the
AddRef/Release in the RCW's Finalize, admittedly this will be
non-deterministic, but it should still keep IEnumerate from leaking.
Ed - 01 Jun 2005 22:25 GMT
> > We have an VB.Net application that uses a COM automation server. There is
> > an object leak that we don't know how to solve.
[quoted text clipped - 16 lines]
> AddRef/Release in the RCW's Finalize, admittedly this will be
> non-deterministic, but it should still keep IEnumerate from leaking.
Thanks for the reply. I agree there is not leak. I did not express the
problem correctly.
The object is released eventually during the garbage collection. What we
have to do is to release it right after the Foreach loop or at least when
the method containing the Foreach return. The automation server does not
function correctly if the release is left for the GC. Calling Collect on GC
after each cal to this method works but we want to avoid the overhead.
Sean Hederman - 02 Jun 2005 05:47 GMT
> The object is released eventually during the garbage collection. What we
> have to do is to release it right after the Foreach loop or at least when
> the method containing the Foreach return. The automation server does not
> function correctly if the release is left for the GC. Calling Collect on
> GC
> after each cal to this method works but we want to avoid the overhead.
Then I'm afraid you'll have to do this manually:
objColl = autoServer.TheCollection
IEnumerator enumerator = objColl.GetEnumerator();
while(enumerator.MoveNext()) {
MemberType objMember = (MemberType) enumerator.Current;
...
System.Runtime.InteropServices.Marshal.ReleaseComObject(objMember)
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(enumerator)
System.Runtime.InteropServices.Marshal.ReleaseComObject(objColl)
If there's any bugs in the above, my bad, I'm tired and grumpy ;-)
Ed - 02 Jun 2005 14:52 GMT
> > The object is released eventually during the garbage collection. What we
> > have to do is to release it right after the Foreach loop or at least when
[quoted text clipped - 16 lines]
>
> If there's any bugs in the above, my bad, I'm tired and grumpy ;-)
I tried that but ReleaseComObject(enumerator) throws a "Specified cast is
not valid" exception.
Sean Hederman - 03 Jun 2005 16:07 GMT
> I tried that but ReleaseComObject(enumerator) throws a "Specified cast is
> not valid" exception.
Whoops, my bad! Yeah, enumerator is not actually an RCW, it's a customer
marshaller that contains the RCW.
Do the following:
object rcwEnumerator = ((ICustomAdapter) enumerator).GetUnderlyingObject();
System.Runtime.InteropServices.Marshal.ReleaseComObject(rcwEnumerator);
Ed - 03 Jun 2005 17:22 GMT
> > I tried that but ReleaseComObject(enumerator) throws a "Specified cast is
> > not valid" exception.
[quoted text clipped - 5 lines]
> object rcwEnumerator = ((ICustomAdapter) enumerator).GetUnderlyingObject();
> System.Runtime.InteropServices.Marshal.ReleaseComObject(rcwEnumerator);
It was a life saver.
Thanks.