Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / June 2005

Tip: Looking for answers? Try searching our database.

Foreach and object leak

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Ed - 01 Jun 2005 05:00 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.

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
Sean Hederman - 01 Jun 2005 06:13 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 - 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.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.