Yes, you don't need a GCHandle here - as Mark mentioned simply store away the reference of the COM objects in a field until they are no longer needed.
-----Original Message----- From: ozdotnet-boun...@ozdotnet.com [mailto:ozdotnet-boun...@ozdotnet.com] On Behalf Of Mark Hurd Sent: Tuesday, October 12, 2010 6:32 AM To: ozDotNet Subject: Re: Use of GCHandle.Alloc and Free On Tue, Oct 12, 2010 at 6:29 PM, Greg Keogh <g...@mira.net> wrote: > Folks, we had a shocking problem today where C# code was listening for > events from a VB6 component. The COM classes exposed by the VB6 app > are nested and a bit complicated to describe, but a nested class which > exposed events was randomly producing the dreaded "COM object that has > been separated from its underlying RCW cannot be used". The random > nature of the problem hinted that it was garbage or dispose related. > After a bit of suffering I found the following solution (feature and > Cursor are COM > classes): > > GCHandle cursorHandle = GCHandle.Alloc(feature.Cursor, > GCHandleType.Normal); > > feature.Cursor.NotifyMoveNext += event handler; > > feature.ShowModalDialog(...); > > if (cursorHandle.IsAllocated) > > { > > cursorHandle.Free(); > > feature.Cursor.NotifyMoveNext -= event handler; > > } > > It used to randomly die on the removal of the event handler. The Alloc > and Free seem to have totally solved the problem. > > This code seems a bit obscure and arcane, so I was wondering if anyone > had comments on it. Perhaps there are better ways. > > Greg It looks to me simply like you need to hold the reference to feature.Cursor until you remove the event handler. To test this, simply change your code to var cursorHolder = feature.Cursor; feature.Cursor.NotifyMoveNext += event handler; feature.ShowModalDialog(...); feature.Cursor.NotifyMoveNext -= event handler; GC.KeepAlive(cursorHolder); Of course if other things are afoot and sometimes cursorHandle.IsAllocated is False, then the above may not be what you need. -- Regards, Mark Hurd, B.Sc.(Ma.)(Hons.)