logo       

Re: should i treat COM Objects as IDisposeable things: msg#00086

windows.devel.dotnet.cx

Subject: Re: should i treat COM Objects as IDisposeable things

Right not sure if this helps anyone but If I add



public object GetIDispatch()

{

return
Marshal.GetTypedObjectForIUnknown(Marshal.GetIUnknownForObject(_comobject),t
ypeof(object));

}



Yes I know yuk, but it seems to increment the ref count on the original
object, because ReleaseCOmObject returns 1 after calling it (whereas before
it was 0)



So it would appear I'm safe if I pass around copies of my original object
via the above method, and call ReleaseCOMObject on it via dispose.



There is also Marshal.ChangeWrapperHandleStrength
<ms-help://MS.MSDNQTR.2005JAN.1033/cpref/html/frlrfsystemruntimeinteropservi
cesmarshalclasschangewrapperhandlestrengthtopic.htm> which could presumably
be used?



bg



-----Original Message-----
From: Barrie Green [mailto:barrie.green@xxxxxxxxxxxxxxxxxxxxx]
Sent: 21 January 2005 15:43
To: DOTNET-CX@xxxxxxxxxxxxxxxxxxx
Subject: Re: [DOTNET-CX] should i treat COM Objects as IDisposeable things



I wonder if Marshal.GetIDispatchForObject will help for me? I'll give it a

go.



All - Thanks for the help



bg



-----Original Message-----

From: Richard Blewett [mailto:richard@xxxxxxxxxxxxxxxxxxx]

Sent: 21 January 2005 15:20

To: DOTNET-CX@xxxxxxxxxxxxxxxxxxx

Subject: Re: [DOTNET-CX] should i treat COM Objects as IDisposeable things



Yep, in this case the second reference is only happening within the realm of

.NET. The interop plumbing knows nothing about it - therefore the refcount

on the RCW is still one which is why yours explodes



Regards



Richatrd Blewett - DevelopMentor

http://www.dotnetconsult.co.uk/weblog

http://www.dotnetconsult.co.uk



> -----Original Message-----

> From: Discussion relating to the specifics of the C# and

> Managed C++ languages [mailto:DOTNET-CX@xxxxxxxxxxxxxxxxxxx]

> On Behalf Of Barrie Green

> Sent: 21 January 2005 15:02

> To: DOTNET-CX@xxxxxxxxxxxxxxxxxxx

> Subject: Re: [DOTNET-CX] should i treat COM Objects as

> IDisposeable things

>

> Right that makes sense, and its rather like how com works I

> guess, the interface that comes back from the rcw is addrefed

> and I have to call ReleaseCOMObject (release) when I want it

> to go away.

>

> I think I still have a problem though because I'm using

> idispatch i.e. I just have an object, and I'm late binding to it.

>

> Unless the same applies to copying:

>

> If I have an object that was created by

> Activator.CreateInstance and I copy it to another object, is

> that doing the internal addreffing for me?

>

> Like

>

> Object comObject = Activator.CreateInstance(.........);

> Object copycomObject = comObject;

>

> I was assuming that this would produce code that would not

> work for me when I did this

>

> Marshal.ReleaseCOMObject(comObject); // would this kill one

> object or zap // the entire underlying wrapper?

> // some time later

> copycomObject.dostuff() // bang!

>

> bg

>

> -----Original Message-----

> From: Richard Blewett [mailto:richard@xxxxxxxxxxxxxxxxxxx]

> Sent: 21 January 2005 14:47

> To: DOTNET-CX@xxxxxxxxxxxxxxxxxxx

> Subject: Re: [DOTNET-CX] should i treat COM Objects as

> IDisposeable things

>

> Say you have a COM object that has an interface something

> like (heres the RCW not the IDL)

>

> class MyCOMObject

> {

> Public MyOtherCOMObject GetOtherCOMObject();

> Public void GiveMeOtherCOMObject(MyOtherCOMObject p);

> Public MyOtherCOMObject GetOtherCOMObjectIJustGaveYou(); }

>

> And you had client code like this:

>

> MyCOMObject foo = new MyCOMObject();

>

> MyOtherCOMObject bar1 = foo.GetOtherCOMObject();

> foo.GiveMeOtherCOMObject(bar1); MyOtherCOMObject bar2 =

> foo.GetOtherCOMObjectIJustGaveYou();

>

> I'm pretty sure that bar1 and bar2 refer to the same RCW but

> it will have an internal ref count of 2 so I can do

>

> Marshal.ReleaseCOMObject(bar1);

>

> And still use bar2 as the ReleaseCOMObject call simply

> decrements the RCW ref count. Its only when I do

>

> Marshal.ReleaseCOMObject(bar2);

>

> That the underlying COM object gets destroyed.

>

> Regards

>

> Richard Blewett - DevelopMentor

> Http://www.dotnetconsult.co.uk/weblog

> Http://www.dotnetconsult.co.uk

>

> > -----Original Message-----

> > From: Discussion relating to the specifics of the C# and

> Managed C++

> > languages [mailto:DOTNET-CX@xxxxxxxxxxxxxxxxxxx]

> > On Behalf Of Barrie Green

> > Sent: 21 January 2005 14:32

> > To: DOTNET-CX@xxxxxxxxxxxxxxxxxxx

> > Subject: Re: [DOTNET-CX] should i treat COM Objects as IDisposeable

> > things

> >

> > Sorry Richard that went straight over my head - what does

> that mean in

> > code (if I can be done simply ;)

> >

> > bg

> >

> > -----Original Message-----

> > From: Richard Blewett [mailto:richard@xxxxxxxxxxxxxxxxxxx]

> > Sent: 21 January 2005 14:18

> > To: DOTNET-CX@xxxxxxxxxxxxxxxxxxx

> > Subject: Re: [DOTNET-CX] should i treat COM Objects as IDisposeable

> > things

> >

> > As in sending the rcw back to the COM sode and then

> retrieving it into

> > another variable (I think this raised the RCW ref count) - it

> > definitely will if you get the reference back to another apartment.

> >

> > Regards

> >

> > Richard Blewett - DevelopMentor

> > Http://www.dotnetconsult.co.uk/weblog

> > Http://www.dotnetconsult.co.uk

> >

> > > -----Original Message-----

> > > From: Discussion relating to the specifics of the C# and

> > Managed C++

> > > languages [mailto:DOTNET-CX@xxxxxxxxxxxxxxxxxxx]

> > > On Behalf Of Barrie Green

> > > Sent: 21 January 2005 13:42

> > > To: DOTNET-CX@xxxxxxxxxxxxxxxxxxx

> > > Subject: Re: [DOTNET-CX] should i treat COM Objects as

> IDisposeable

> > > things

> > >

> > > What do u mean by "marshalling a new ref through COM",

> > create another

> > > (COM) Object?

> > >

> > > Object o1 = activator.blahblah("progid"); // one ref Object

> > > o2 = activator.blahblah("progid"); // second ref

> > >

> > > Not this surely?

> > >

> > > bg

> > >

> > > -----Original Message-----

> > > From: Matthew W. Adams [mailto:mwa@xxxxxxxxxxxxxxxxxxxxxx]

> > > Sent: 21 January 2005 12:58

> > > To: DOTNET-CX@xxxxxxxxxxxxxxxxxxx

> > > Subject: Re: [DOTNET-CX] should i treat COM Objects as

> IDisposeable

> > > things

> > >

> > > Thanks Richard - much more succinctly put than me!

> > >

> > > Plus there's the all-new Whidbey API... is it called

> > > ReleaseComObjectFinal, or FinalReleaseComObject, or

> similar, which

> > > also forces a release, regardless of concurrency issues.

> > >

> > > Further, the RCW has an optimization that it *doesn't* addref for

> > > multiple users inside an MTA, so the ref count can be all to heck

> > > anyway, IIRC.

> > >

> > > M

> > >

> > > Matthew Adams

> > > Director of R&D

> > > Digital Healthcare Ltd

> > >

> > > > -----Original Message-----

> > > > From: Discussion relating to the specifics of the C# and

> > > Managed C++

> > > > languages [mailto:DOTNET-CX@xxxxxxxxxxxxxxxxxxx] On Behalf

> > > Of Richard

> > > > Blewett

> > > > Sent: 21 January 2005 12:49

> > > > To: DOTNET-CX@xxxxxxxxxxxxxxxxxxx

> > > > Subject: Re: [DOTNET-CX] should i treat COM Objects as

> > IDisposeable

> > > things

> > > >

> > > > I think what Matthew is referring to is if you pass the

> > reference to

> > > the

> > > > RCW

> > > > around on the .NET side (rather than marshalling a new

> ref through

> > > COM)

> > > > then

> > > > the RCW doesn't know about the new .NET ref and so can't up its

> > > internal

> > > > ref

> > > > count

> > > >

> > > > Richard Blewett - DevelopMentor

> > > > http://www.dotnetconsult.co.uk/weblog

> > > > http://www.dotnetconsult.co.uk

> > > >

> > > > > -----Original Message-----

> > > > > From: Discussion relating to the specifics of the C# and

> > > Managed C++

> > > > > languages [mailto:DOTNET-CX@xxxxxxxxxxxxxxxxxxx]

> > > > > On Behalf Of Ian Griffiths

> > > > > Sent: 21 January 2005 12:10

> > > > > To: DOTNET-CX@xxxxxxxxxxxxxxxxxxx

> > > > > Subject: Re: [DOTNET-CX] should i treat COM Objects as

> > > IDisposeable

> > > > > things

> > > > >

> > > > > I thought the RCW had its own reference count, one which was

> > > > > independent of the COM reference count.

> > > > >

> > > > > My understanding was that the RCW reference count gets

> > > incremented

> > > > > each time you marshal the COM object into the AppDomain

> > > through an

> > > > > interop boundary of some kind. It is decremented each

> > > time you call

> > > > > Marshal.ReleaseComObject. And the RCW doesn't really call

> > > > > IUnknown::Release on the underlying COM object until its own

> > > > > reference count drops to zero.

> > > > >

> > > > > So if you write code like this:

> > > > >

> > > > > // assume for this example that 'something'

> > > > > // is a COM object, so this next line is

> > > > > // making a COM interop call to a method that

> > > > > // returns a COM interface.

> > > > >

> > > > > ISomeInterface obj = something.GetComObject();

> > > > >

> > > > > obj.DoStuff();

> > > > > Marshal.ReleaseComObject(obj);

> > > > >

> > > > > The first line will increment the RCW's reference

> > count, and the

> > > > > final line will decrement it. If some other part of the

> > > program was

> > > > > using the same COM object, it would already have caused

> > the RCW's

> > > > > reference count to be 1 or more. So this snippet of code

> > > here won't

> > > > > cause the RCW ref count to drop to 0, meaning that it

> > won't cause

> > > > > the underlying COM object to be released.

> > > > >

> > > > > In other words, using Marshal.ReleaseComObject() doesn't

> > > necessarily

> > > > > mess things up for other users of the same RCW.

> > > > >

> > > > > At least I *thought* that was how it worked last time I

> > > wrote some

> > > > > tests...

> > > > >

> > > > > I've occasionally seen people do this:

> > > > >

> > > > > // Barf

> > > > > while (Marshal.ReleaseComObject(obj) > 0) { }

> > > > >

> > > > > Because ReleaseComObject always returns the current RCW

> > reference

> > > > > count (and this *is* guaranteed to be the case, unlike

> > the return

> > > > > value of

> > > > > IUnknown::Release) this is way of forcing the RCW to be

> > > torn down.

> > > > > And this definitely will mess you up if other bits of

> > > your program

> > > > > are using the same COM object. I'd never do this -

> if you ever

> > > > > think you need to do this, a better solution is probably

> > > to work out

> > > > > why your RCW seems to have more outstanding

> references than you

> > > > > thought it should...

> > > > >

> > > > > Of course there's also Marshal.Release() - that's an

> > > altogether more

> > > > > grungy thing though.

> > > > >

> > > > >

> > > > > --

> > > > > Ian Griffiths

> > > > >

> > > > > > -----Original Message-----

> > > > > > From: Matthew W. Adams

> > > > > >

> > > > > > But beware of using multiple instances of the COM object

> > > > > (via its RCW)

> > > > > > concurrently. I believe that the RCW can reuse the

> > > underlying COM

> > > > > object

> > > > > > it allocated on your behalf, and Marshal.ReleaseComObject

> > > > > will release

> > > > > > that underlying instance, regardless of the number of RCW

> > > references

> > > > > to

> > > > > > it.

> > > > > >

> > > > > > M

> > > > > >

> > > > > > Matthew Adams

> > > > > > Director of R&D

> > > > > > Digital Healthcare

> > > > > >

> > > > > > > -----Original Message-----

> > > > > > > From: Discussion relating to the specifics of the C# and

> > > > > Managed C++

> > > > > > > languages [mailto:DOTNET-CX@xxxxxxxxxxxxxxxxxxx] On

> > > > > Behalf Of I D. G

> > > > > > > Sent: 20 January 2005 21:56

> > > > > > > To: DOTNET-CX@xxxxxxxxxxxxxxxxxxx

> > > > > > > Subject: Re: [DOTNET-CX] should i treat COM Objects as

> > > > > IDisposeable

> > > > > > things

> > > > > > >

> > > > > > > As a general rule, yes, you should. (And yes,

> > > > > > Marshal.ReleaseComObject

> > > > > > > is the one to use.) If you don't you'll be waiting

> > > until the GC

> > > > > runs

> > > > > > > before your COM objects get released.

> > > > > > >

> > > > > > > There may be cases where this doesn't matter - it

> depends on

> > > your

> > > > > COM

> > > > > > > objects. But unless you are absolutely certain that you

> > > > > don't care

> > > > > > when

> > > > > > > they get released, you need to make sure you release them

> > > > > manually.

> > > > > > > (And also, bear in mind that there are some costs

> associated

> > > with

> > > > > > > interop wrappers. So even if you don't need the

> COM objects

> > > > > > themselves

> > > > > > > to be released in a timely fashion, it might be

> > worth doing it

> > > > > anyway.

> > > > > > > (It would depend on how many you create, and how long you

> > > normally

> > > > > use

> > > > > > > them for.)

> > > > > > >

> > > > > > >

> > > > > > > --

> > > > > > > Ian Griffiths

> > > > > > >

> > > > > > > > -----Original Message-----

> > > > > > > > From: Barrie Green

> > > > > > > >

> > > > > > > > If I have a wrapper around a Com object like this

> > > > > > > >

> > > > > > > > class LateBoundCOMObject

> > > > > > > > {

> > > > > > > > object _comObject;

> > > > > > > >

> > > > > > > > public LateBoundCOMObject(string ProgID)

> > > > > > > > {

> > > > > > > >

> > > > > > Activator.CreateInstance(Type.GetTypeFromProgID(ProgID));

> > > > > > > > }

> > > > > > > >

> > > > > > > > public object Invoke(string methodName,

> > > params object

> > > []

> > > > > > args)

> > > > > > > > {

> > > > > > > > return Invoke(methodName,

> > > BindingFlags.InvokeMethod,

> > > > > > > args);

> > > > > > > > }

> > > > > > > >

> > > > > > > > public object Invoke(string methodName,

> > BindingFlags

> > > > > > > bindingFlags,

> > > > > > > > params object [] args)

> > > > > > > > {

> > > > > > > > return

> > > _comObject.GetType().InvokeMember(methodName,

> > > > > > > > bindingFlags, null, _comObject, args);

> > > > > > > > }

> > > > > > > > }

> > > > > > > >

> > > > > > > >

> > > > > > > > Should I implement IDisposable and release/destroy the

> > > > > object in a

> > > > > > > > finalizer/dispose pattern? Or should I let the

> > > runtime do it -

> > > > > > > presumably

> > > > > > > > by

> > > > > > > > a collection?

> > > > > > > >

> > > > > > > > If yes should I use Marshal.ReleaseComObject - I'm sure

> > > > > I've seen

> > > > > > > > something bad about using this somewhere.

> > > > > > >

> > > > > > > ===================================

> > > > > > > This list is hosted by DevelopMentor(r)

> > > http://www.develop.com

> > > > > > >

> > > > > > > View archives and manage your subscription(s) at

> > > > > > > http://discuss.develop.com

> > > > > >

> > > > > > ===================================

> > > > > > This list is hosted by DevelopMentor(r)

> > http://www.develop.com

> > > > > >

> > > > > > View archives and manage your subscription(s) at

> > > > > > http://discuss.develop.com

> > > > >

> > > > > ===================================

> > > > > This list is hosted by DevelopMentor. http://www.develop.com

> > > > >

> > > > > View archives and manage your subscription(s) at

> > > > > http://discuss.develop.com

> > > > >

> > > > > --

> > > > > No virus found in this incoming message.

> > > > > Checked by AVG Anti-Virus.

> > > > > Version: 7.0.300 / Virus Database: 265.7.1 - Release Date:

> > > 19/01/2005

> > > > >

> > > > >

> > > >

> > > > --

> > > > No virus found in this outgoing message.

> > > > Checked by AVG Anti-Virus.

> > > > Version: 7.0.300 / Virus Database: 265.7.1 - Release Date:

> > > 19/01/2005

> > > >

> > > > ===================================

> > > > This list is hosted by DevelopMentor(r) http://www.develop.com

> > > >

> > > > View archives and manage your subscription(s) at

> > > > http://discuss.develop.com

> > >

> > > ===================================

> > > This list is hosted by DevelopMentor(r) http://www.develop.com

> > >

> > > View archives and manage your subscription(s) at

> > > http://discuss.develop.com

> > >

> > > ===================================

> > > This list is hosted by DevelopMentor(r) http://www.develop.com

> > >

> > > View archives and manage your subscription(s) at

> > > http://discuss.develop.com

> > >

> > > --

> > > No virus found in this incoming message.

> > > Checked by AVG Anti-Virus.

> > > Version: 7.0.300 / Virus Database: 265.7.1 - Release Date:

> > 19/01/2005

> > >

> > >

> >

> > --

> > No virus found in this outgoing message.

> > Checked by AVG Anti-Virus.

> > Version: 7.0.300 / Virus Database: 265.7.1 - Release Date:

> 19/01/2005

> >

> >

> > ===================================

> > This list is hosted by DevelopMentor(r) http://www.develop.com

> >

> > View archives and manage your subscription(s) at

> > http://discuss.develop.com

> >

> > ===================================

> > This list is hosted by DevelopMentor(r) http://www.develop.com

> >

> > View archives and manage your subscription(s) at

> > http://discuss.develop.com

> >

> > --

> > No virus found in this incoming message.

> > Checked by AVG Anti-Virus.

> > Version: 7.0.300 / Virus Database: 265.7.1 - Release Date:

> 19/01/2005

> >

> >

>

> --

> No virus found in this outgoing message.

> Checked by AVG Anti-Virus.

> Version: 7.0.300 / Virus Database: 265.7.1 - Release Date: 19/01/2005

>

>

> ===================================

> This list is hosted by DevelopMentor(r) http://www.develop.com

>

> View archives and manage your subscription(s) at

> http://discuss.develop.com

>

> ===================================

> This list is hosted by DevelopMentor(r) http://www.develop.com

>

> View archives and manage your subscription(s) at

> http://discuss.develop.com

>

> --

> No virus found in this incoming message.

> Checked by AVG Anti-Virus.

> Version: 7.0.300 / Virus Database: 265.7.1 - Release Date: 19/01/2005

>

>



--

No virus found in this outgoing message.

Checked by AVG Anti-Virus.

Version: 7.0.300 / Virus Database: 265.7.1 - Release Date: 19/01/2005





===================================

This list is hosted by DevelopMentor(r) http://www.develop.com



View archives and manage your subscription(s) at http://discuss.develop.com



===================================

This list is hosted by DevelopMentor(r) http://www.develop.com



View archives and manage your subscription(s) at http://discuss.develop.com


===================================
This list is hosted by DevelopMentor® http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com



<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise