COM+ object not being released back to the pool

V

VinDotNet

Here's the Scenario I am facing:
I've got a winform managed c++ client which connects to my managed
COM+ server application (by making createinstance, then typecasting
the object to an interface, then calling methods over it). This COM+
server application is from a C# dll that has references to Interop dlls
(com type libraries written in unmanaged c++) and MC++ wrappers over
unmanaged c++ code. I've got object pooling enabled with (Min : 0 and
Max : 1048576). I've got a db connection in the construct() method of
the servicedcomponent.

I am on
1. VS.Net 2003
2. .Net framework 1.1
3. COM+ is a server application with JIT disabled, object pooling
enabled.

Issue:
When I run the winform client for the first time, everything goes well.
But when I close it the object stays there and isn't released back to
the pool. I mean in the component services mmc, event statistics i can
see Objects: 1 Activated: 1 Pooled: 1.

If I invoke my COM+ component from a vbscript, C# client, unmanaged c++
client (by cocreateinstance()) the objects are being returned back to
the pool properly. Point to note here is I don't even call the
ServicedComponent.DisposeObject() at client.
Whereas it doesn't work in my above scenario (winform managed c++)
client even after I do a disposeobject or Marshal.ReleaseComObject().

No matter what, the objects keep on growing as many no of clients
getting connected.

1. How to make them released back to the pool immediately as the client
is closed? or what am I doing wrong here?

Could you please help me out to resolve this issue. I've searched over
the web everywhere, read many of answers to these kind of
questions in newsgroups, tried various options, but I am yet to find a
solution.
Here's a list of options I tried and couldn't succeed.
1. ServicedComponent.DisposeObject(obj); at the client.
2. Called Marshal.ReleaseComObject(interop object) at the client.
Released all com objects.
3. ServicedComponent.DisposeObject(this); at the server, just after
deactivate() and disconnect().
4. Called Marshal.ReleaseComObject(interop object) at the server.
Released all com objects.
5. Deactivate() was not getting called when winform client closes. So
I tried forcibly calling it from server's disconnect method. Didn't
work.
6. Set JIT activation to true in component's properties.
7. Set Object pooling disabled in component's properties.

2. Also one more question, if my object pooling is enabled, and the
construct() method of servicedcomponent is called everytime a request
comes, does it mean object pooling is of no use here? In object
pooling, if a second request comes, isn't it not supposed to invoke
construct() and directly call activate()?

Thanks and Regards,
Vin
 
N

Nicholas Paldino [.NET/C# MVP]

Vin,

It is interesting that it works for VBScript and unmanaged C++ AND ALSO
for a C# client. If the C# client didn't work, I would say that you have an
issue with not releasing references correctly. However, the C# client
releasing correctly is what gives me pause.

Do you have the AutoComplete attribute on any of the methods which will
cause JIT activation to occur? I recall reading somewhere that this was
required for JIT to function correctly (even though it is primarily
associated with transactions). If you do not, and you apply it, does it
work then?

Also, I am not sure you should be creating the database connection in
the call to Construct. The only scenario where I can see this working is
where you have the database connection created, but not opened in the call
to construct, and in the activate and deactivate calls for JIT, you open and
close the connection respectively. If you open it in the call to Construct,
I think you will have some problems.

Now, in your managed C++ code, you say you are calling CreateInstance (I
assume you mean CoCreateInstance here). Why not use the managed
representation of the class (like you do in the C# client)? The CLR will
wire up everything for you, and you will probably get the behavior that you
want.

Hope this helps.
 
W

Willy Denoyette [MVP]

VinDotNet said:
Here's the Scenario I am facing:
I've got a winform managed c++ client which connects to my managed
COM+ server application (by making createinstance, then typecasting
the object to an interface, then calling methods over it). This COM+
server application is from a C# dll that has references to Interop dlls
(com type libraries written in unmanaged c++) and MC++ wrappers over
unmanaged c++ code. I've got object pooling enabled with (Min : 0 and
Max : 1048576). I've got a db connection in the construct() method of
the servicedcomponent.

I am on
1. VS.Net 2003
2. .Net framework 1.1
3. COM+ is a server application with JIT disabled, object pooling
enabled.

Issue:
When I run the winform client for the first time, everything goes well.
But when I close it the object stays there and isn't released back to
the pool. I mean in the component services mmc, event statistics i can
see Objects: 1 Activated: 1 Pooled: 1.

If I invoke my COM+ component from a vbscript, C# client, unmanaged c++
client (by cocreateinstance()) the objects are being returned back to
the pool properly. Point to note here is I don't even call the
ServicedComponent.DisposeObject() at client.
Whereas it doesn't work in my above scenario (winform managed c++)
client even after I do a disposeobject or Marshal.ReleaseComObject().

No matter what, the objects keep on growing as many no of clients
getting connected.

1. How to make them released back to the pool immediately as the client
is closed? or what am I doing wrong here?

Could you please help me out to resolve this issue. I've searched over
the web everywhere, read many of answers to these kind of
questions in newsgroups, tried various options, but I am yet to find a
solution.
Here's a list of options I tried and couldn't succeed.
1. ServicedComponent.DisposeObject(obj); at the client.
2. Called Marshal.ReleaseComObject(interop object) at the client.
Released all com objects.
3. ServicedComponent.DisposeObject(this); at the server, just after
deactivate() and disconnect().
4. Called Marshal.ReleaseComObject(interop object) at the server.
Released all com objects.
5. Deactivate() was not getting called when winform client closes. So
I tried forcibly calling it from server's disconnect method. Didn't
work.
6. Set JIT activation to true in component's properties.
7. Set Object pooling disabled in component's properties.

2. Also one more question, if my object pooling is enabled, and the
construct() method of servicedcomponent is called everytime a request
comes, does it mean object pooling is of no use here? In object
pooling, if a second request comes, isn't it not supposed to invoke
construct() and directly call activate()?

Thanks and Regards,
Vin

ServicedComponent.DisposeObject(yourobj);
should definitely work.
Mind to post your code or at least a repro case?

To answer your second question, Contruct should only be called when
constructing a new object, it should not be called if there are objects
available from the pool, are you sure you return true from your CanBePooled
method?

Willy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top