Re: Use of GCHandle.Alloc and Free

2010-10-31 Thread Richard Mason
Or perhaps use GC.KeepAlive

On Mon, Nov 1, 2010 at 9:34 AM, David Kean  wrote:

>  If by using a local variable you mean local field, then yes this is
> reliable.
>
>
>
> *From:* ozdotnet-boun...@ozdotnet.com [mailto:
> ozdotnet-boun...@ozdotnet.com] *On Behalf Of *Greg Keogh
> *Sent:* Sunday, October 31, 2010 1:44 PM
> *To:* 'ozDotNet'
> *Subject:* FW: Use of GCHandle.Alloc and Free
>
>
>
> You may recall two weeks ago I had to use code like this to stop a COM
> object from being collected:
>
>
>
> GCHandle cursorHandle = GCHandle.Alloc(feature.Cursor,
> GCHandleType.Normal);
>
>
>
> A few people suggested that it was overkill and simply making a local
> variable reference to feature.Cursor would fix the problem.
>
>
>
> It does!
>
>
>
> Although I wonder if using a dummy reference is reliable. In Debug mode it
> works, but in Release mode might it get optimised away and my problem will
> return? I didn’t try it.
>
>
>
> Greg
>


RE: Use of GCHandle.Alloc and Free

2010-10-31 Thread David Kean
If by using a local variable you mean local field, then yes this is reliable.

From: ozdotnet-boun...@ozdotnet.com [mailto:ozdotnet-boun...@ozdotnet.com] On 
Behalf Of Greg Keogh
Sent: Sunday, October 31, 2010 1:44 PM
To: 'ozDotNet'
Subject: FW: Use of GCHandle.Alloc and Free

You may recall two weeks ago I had to use code like this to stop a COM object 
from being collected:

GCHandle cursorHandle = GCHandle.Alloc(feature.Cursor, GCHandleType.Normal);

A few people suggested that it was overkill and simply making a local variable 
reference to feature.Cursor would fix the problem.

It does!

Although I wonder if using a dummy reference is reliable. In Debug mode it 
works, but in Release mode might it get optimised away and my problem will 
return? I didn't try it.

Greg


FW: Use of GCHandle.Alloc and Free

2010-10-31 Thread Greg Keogh
You may recall two weeks ago I had to use code like this to stop a COM
object from being collected:

 

GCHandle cursorHandle = GCHandle.Alloc(feature.Cursor, GCHandleType.Normal);

 

A few people suggested that it was overkill and simply making a local
variable reference to feature.Cursor would fix the problem.

 

It does!

 

Although I wonder if using a dummy reference is reliable. In Debug mode it
works, but in Release mode might it get optimised away and my problem will
return? I didn't try it.

 

Greg



RE: Use of GCHandle.Alloc and Free

2010-10-12 Thread Greg Keogh
>I might be off track, but don't you need to call
>`Marshall.ReleaseComObject(object)` on all managed references to COM

The VB6 programmers wants the 'feature' objects (there a multiple ones) and
the 'Cursor' inside each one to live for the lifetime of the App. I didn't
mention it, but there is a kind of factory class that makes the COM objects
for me and it knows when to ReleaseComObject on them all at shutdown time.
So I *hope* their lifetimes are managed correctly, but with COM there is so
much magic stuff happening I can't shake off this fear that something rotten
is happening that I can't see. It seems to be working correctly anyway,
which is a good sign I guess!

Mark, David, I'll try the change you suggested with a simple reference and
let you know what happens. I didn't think of doing that because I already
had an event listener on the object and I thought that would be enough to
keep it alive.

Greg



RE: Use of GCHandle.Alloc and Free

2010-10-12 Thread James Chapman-Smith
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: ozdotnet-boun...@ozdotnet.com [mailto:ozdotnet-boun...@ozdotnet.com]
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: 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  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.)



RE: Use of GCHandle.Alloc and Free

2010-10-12 Thread David Kean
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  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.)



Re: Use of GCHandle.Alloc and Free

2010-10-12 Thread Mark Hurd
On Tue, Oct 12, 2010 at 6:29 PM, Greg Keogh  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.)


Use of GCHandle.Alloc and Free

2010-10-12 Thread Greg Keogh
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