COM Interop - switching to STA Threading - how to?

P

Peter Duniho

Simon said:
[...]
although the factory gets instantiated fine, I get an unhandle COM
exception error when the factory tries to create the constructedObject.
(FYI, I do have unit tests proving that this is okay in a pure COM
environment)

Well, as before, until you post a concise-but-complete code example, it
will not be possible to provide specific advice on an error you get,
especially without any other information about the error (exact text, in
what thread it occurs, what program statement, etc...the kinds of things
someone debugging the problem first-hand would be looking at in a debugger).

My experiment proves to me that a plain STA COM object created in a STA
thread works fine, with .NET or COM automatically handling
marshaling/proxying from other threads once you've got the managed
object representing the COM object. If you are getting an exception,
you either have some important difference from that scenario in your own
code, or an altogether unrelated bug somewhere else in your code.
Either way, without a concise-but-complete code example, I don't see how
the problem can be diagnosed by anyone other than you.

Pete
 
S

Simon Woods

Simon said:
[...]
although the factory gets instantiated fine, I get an unhandle COM
exception error when the factory tries to create the
constructedObject. (FYI, I do have unit tests proving that this is
okay in a pure COM environment)

Well, as before, until you post a concise-but-complete code example, it
will not be possible to provide specific advice on an error you get,
especially without any other information about the error (exact text, in
what thread it occurs, what program statement, etc...the kinds of things
someone debugging the problem first-hand would be looking at in a
debugger).

My experiment proves to me that a plain STA COM object created in a STA
thread works fine, with .NET or COM automatically handling
marshaling/proxying from other threads once you've got the managed
object representing the COM object. If you are getting an exception, you
either have some important difference from that scenario in your own
code, or an altogether unrelated bug somewhere else in your code. Either
way, without a concise-but-complete code example, I don't see how the
problem can be diagnosed by anyone other than you.

Pete

Well you sorted it! I had to make a change to increase the scope of one
of the COM Objects. It was previously declared private (but
implementing a public interface) but I needed to increase it's
visibility to public-not-creatable. Strange, since it works fine in a
pure COM (VB6) environment.

I know you've given me much of your time (and please don't feel you need
to respond since these more general questions), but I wondered if you
had any thoughts on how you think this will scale. Would it be worth
making a pool of these?

Having said all that, not only have you provided a solution, but there
is so much from which I can learn from what you've done here. "Thx"
seems a bit paltry, but thank you very much.

Simon
 
P

Peter Duniho

Simon said:
[...]
I know you've given me much of your time (and please don't feel you need
to respond since these more general questions), but I wondered if you
had any thoughts on how you think this will scale. Would it be worth
making a pool of these?

IMHO it's almost always worth pooling costly resources like COM objects,
factories, STA threads, etc.

However, to some extent, the mere fact that you're using STA-only COM
objects may always cause issues. All that proxying can be bad for
performance, and the more objects you have all vying for attention from
the same thread, the worst that will be (but dedicating a thread to each
object will cause other, different performance problems, so you're stuck
either way :( ).

You may be able to improve things somewhat by using the suggestion I
made, regarding using the MessageWindowInvoker class to access your COM
objects, so that you avoid the proxying overhead (assuming .NET/COM is
smart enough to detect that and avoid proxying...I suspect it is).
Essentially, you wind up handling the multi-thread issues at a higher
level, where they can be addressed through simple synchronization rather
than using proxy objects.

But in the end, the best way to avoid performance problems and allow it
to scale well would be to rewrite it as MTA COM objects that don't need
all that marshaling. Or even as native C# managed objects, leaving COM
behind. You'll still have to mind your threading p's and q's to avoid
scaling-detrimental problems, but they should be easier to deal with and
in any case will be much more directly under your control.

Of course, all this depends on how much time your application spends
dealing with these COM objects. Even if they are expensive to use, if
they aren't a significant proportion of the execution of your
application, even dramatic improvements in performance related to the
COM objects isn't going to show up in the end-user experience.

That's where good performance measurements and goals come in. Just be
careful to not waste time optimizing something that isn't actually
slowing your application down. :)
Having said all that, not only have you provided a solution, but there
is so much from which I can learn from what you've done here. "Thx"
seems a bit paltry, but thank you very much.

Sure, happy to help as I can. You're welcome!

Pete
 

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

Similar Threads


Top