I might be off track, but don't you need to call
`Marshall.ReleaseComObject(object)` on all managed references to COM
objects? My experience a few years back was that when you allocated and
released COM objects many times you run out of some sort of handle that then
causes things to randomly screw up. But by calling `ReleaseComObject`
everything went fine.

-----Original Message-----
From: [email protected] [mailto:[email protected]]
On Behalf Of David Kean
Sent: Wednesday, 13 October 2010 01:41
To: ozDotNet
Subject: RE: Use of GCHandle.Alloc and Free

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: [email protected] [mailto:[email protected]]
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 <[email protected]> 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.)

Reply via email to