[STAThread]

M

Martijn Mulder

What is the penalty if I do not put [STAThread] just above the Main()
method?
 
J

Jon Skeet [C# MVP]

Martijn Mulder said:
What is the penalty if I do not put [STAThread] just above the Main()
method?

Well, if you use COM components that rely on being on an STA thread,
they may well break. Many of the WinForms components fall into that
category.

If you're just writing a console app and not using any COM components,
you should be fine.
 
M

Martijn Mulder

What is the penalty if I do not put [STAThread] just above the Main()
Well, if you use COM components that rely on being on an STA thread,
they may well break. Many of the WinForms components fall into that
category.

If you're just writing a console app and not using any COM components,
you should be fine.


Thank you. You are very kind to take the time to answer my more or less
foolish questions :)
 
M

Michael Nemtsev

Hello Martijn,

MM> What is the penalty if I do not put [STAThread] just above the
MM> Main() method?

Adding to the Jon, STAThread changes the apartment state of the current thread
to be single threaded. it's required for WinForms mostly, because it doesn't
support MTA or free threaded apartment. (read there http://blogs.msdn.com/jfoscoding/archive/2005/04/07/406341.aspx)

Without this apartment type will be Unknown, as the thread would not have
entered an apartment yet.

MTA is appropriate for back-end, server side, where u work with COM/COM+

---
WBR,
Michael Nemtsev :: blog: http://spaces.msn.com/laflour

"At times one remains faithful to a cause only because its opponents do not
cease to be insipid." (c) Friedrich Nietzsche
 
J

Jon Skeet [C# MVP]

Michael Nemtsev said:
MTA is appropriate for back-end, server side, where u work with COM/COM+

Well, that depends on the COM components you're working with. If you're
unlucky enough to be working with COM components which require STAs,
you still need [STAThread] :(
 
M

Michael Nemtsev

Hello Jon Skeet [C# MVP],

J> Well, that depends on the COM components you're working with. If
J> you're unlucky enough to be working with COM components which require
J> STAs, you still need [STAThread] :(

Yep, it is so.

---
WBR,
Michael Nemtsev :: blog: http://spaces.msn.com/laflour

"At times one remains faithful to a cause only because its opponents do not
cease to be insipid." (c) Friedrich Nietzsche
 
W

Willy Denoyette [MVP]

| > MTA is appropriate for back-end, server side, where u work with COM/COM+
|
| Well, that depends on the COM components you're working with. If you're
| unlucky enough to be working with COM components which require STAs,
| you still need [STAThread] :(
|

Not exactly, a COM object will be created to run in a compatible apartment
irrespective the apartment state of the calling thread.
Say you have a COM object marked as 'Apartment' threaded, so it needs an STA
to run in, and you create an instance from an in-compatible thread (MTA). In
this case COM will, or, create the object in the default STA (the first
thread in the process initialized as STA) or will create an STA thread
(owned by COM) if no such thread exists, and the creator will get a proxy
back. All accesses to the COM object will have to get marshaled (using the
proxy), this involves some marshaling overhead which you can eliminate
completely when creating the object in a compatible apartment, but it works,
that's the beauty of COM.

Willy.
 
M

Michael Nemtsev

Hello Willy Denoyette [MVP],

Yep, but if u are working with UI-orient COM object u still need to appy
[STAThread] to get synchronization with UI controls.
Seems that Jon took this into account


W> W> | > MTA is appropriate for back-end, server side, where u work with
W> COM/COM+
W> |
W> | Well, that depends on the COM components you're working with. If
W> you're
W> | unlucky enough to be working with COM components which require
W> STAs,
W> | you still need [STAThread] :(
W> |
W> Not exactly, a COM object will be created to run in a compatible
W> apartment
W> irrespective the apartment state of the calling thread.
W> Say you have a COM object marked as 'Apartment' threaded, so it needs
W> an STA
W> to run in, and you create an instance from an in-compatible thread
W> (MTA). In
W> this case COM will, or, create the object in the default STA (the
W> first
W> thread in the process initialized as STA) or will create an STA
W> thread
W> (owned by COM) if no such thread exists, and the creator will get a
W> proxy
W> back. All accesses to the COM object will have to get marshaled
W> (using the
W> proxy), this involves some marshaling overhead which you can
W> eliminate
W> completely when creating the object in a compatible apartment, but it
W> works,
W> that's the beauty of COM.
W> Willy.
W>
---
WBR,
Michael Nemtsev :: blog: http://spaces.msn.com/laflour

"At times one remains faithful to a cause only because its opponents do not
cease to be insipid." (c) Friedrich Nietzsche
 
J

Jon Skeet [C# MVP]

Michael Nemtsev said:
Yep, but if u are working with UI-orient COM object u still need to appy
[STAThread] to get synchronization with UI controls.
Seems that Jon took this into account

Nah - I hardly know anything about COM. I've seen various things about
COM marshalling "just working" that never seemed to "just work" when I
tried it. My knowledge is very flaky in this area. I want it to stay
that way in some senses - I hope to have very little to so with it!
 
W

Willy Denoyette [MVP]

| Hello Willy Denoyette [MVP],
|
| Yep, but if u are working with UI-orient COM object u still need to appy
| [STAThread] to get synchronization with UI controls.
| Seems that Jon took this into account
|

That's a different issue, ActiveX visual controls (what you call UI oriented
COM objects) or are all apartment threaded, they need a message pumping
thread to run in (which is provided by COM if created in the main STA
thread), and because they create windows (HWND's) they have UI thread
affinity, but this is a 'windows' requirement it has nothing to do with COM.
In short, ActiveX controls must have their message queue pumped by the UI
thread.

Willy.
 
W

Willy Denoyette [MVP]

| > Yep, but if u are working with UI-orient COM object u still need to appy
| > [STAThread] to get synchronization with UI controls.
| > Seems that Jon took this into account
|
| Nah - I hardly know anything about COM. I've seen various things about
| COM marshalling "just working" that never seemed to "just work" when I
| tried it. My knowledge is very flaky in this area. I want it to stay
| that way in some senses - I hope to have very little to so with it!
|
|

Well, you can hardly stay out of it, remember .NET on Windows is COM3 :),
take away COM and look what's left. Also, don't believe that COM is going
away, it's just moving down from the user level to the system level, Vista
has a lot more COM components added than there are .NET components. Actually
Vista can run without .NET, but it can't without COM.
Note that I'm not talking about technologies built on top of COM (like
ActiveX, OLE etc), I'm talking about the low level COM binary interface
standard, which makes it possible for software components (whatever
language) to interoperate seamlessly using a well defined standard
interface.
Once you understand the COM interface definitions (the object model) and
it's rules, you'll better understand why/how things are working (or fail).

Willy.
 
J

Jon Skeet [C# MVP]

Willy Denoyette said:
| Nah - I hardly know anything about COM. I've seen various things about
| COM marshalling "just working" that never seemed to "just work" when I
| tried it. My knowledge is very flaky in this area. I want it to stay
| that way in some senses - I hope to have very little to so with it!

Well, you can hardly stay out of it, remember .NET on Windows is COM3 :),
take away COM and look what's left.

Quite a lot, IMO. Put it this way - I doubt that Mono on Linux uses
COM, and it still manages to be useful. Java doesn't use COM (at least
not on non-Windows platforms) and manages to achieve many of the same
things as .NET. I don't see why COM is a necessary part of applications
which don't appear to naturally require it.
Also, don't believe that COM is going
away, it's just moving down from the user level to the system level, Vista
has a lot more COM components added than there are .NET components. Actually
Vista can run without .NET, but it can't without COM.

Fine, I can live with that.
Note that I'm not talking about technologies built on top of COM (like
ActiveX, OLE etc), I'm talking about the low level COM binary interface
standard, which makes it possible for software components (whatever
language) to interoperate seamlessly using a well defined standard
interface.
Once you understand the COM interface definitions (the object model) and
it's rules, you'll better understand why/how things are working (or
fail).

Hmm... unfortunately, in my limited experience things don't quite work
as they're meant to. For instance, the way you expressed the use of COM
in a previous message suggested that if I'm using a COM wrapper that
requires an STA, it's more efficient to specify STAThread but that
things should still work without, via marshalling. Well, thinking of
the one time I've definitely had to use COM explicitly in C#, things
didn't work at all without STAThread. (I can't remember the exact error
message, unfortunately.) It could very well be that this was a badly
written COM library, but my impression from messages I've read over the
years is that there are more badly written bits of COM than well
written ones...
 
W

Willy Denoyette [MVP]

| > | Nah - I hardly know anything about COM. I've seen various things about
| > | COM marshalling "just working" that never seemed to "just work" when I
| > | tried it. My knowledge is very flaky in this area. I want it to stay
| > | that way in some senses - I hope to have very little to so with it!
| >
| > Well, you can hardly stay out of it, remember .NET on Windows is COM3
:),
| > take away COM and look what's left.
|
| Quite a lot, IMO. Put it this way - I doubt that Mono on Linux uses
| COM, and it still manages to be useful. Java doesn't use COM (at least
| not on non-Windows platforms) and manages to achieve many of the same
| things as .NET. I don't see why COM is a necessary part of applications
| which don't appear to naturally require it.
|

True, but that's because Linux doesn't have COM. That means you don't need
to interop with existing COM servers (like the Office product suite,
Exchange server, a zillion of VB6 applications....). Believe me, without
COM, .NET would have died before it was even born, for the same reason why
Java failed on the Windows client. Note also that Windows isn't Unix or
Linux, most existing applications on windows are COM based (directly or
under the covers). Services like Exchange, SQL Server and many more expsose
their functionality to the external world through COM. Internally, they use
COM as a glue in order to build complex systems using an higly modular
design (look at SQL server and count the number of COM dll's included in bin
and bi.
To get an idea about the number of COM interfaces available in a system,
watch your registry and count the number of COM classes registered, you
might be suprised.

Nor does it have to interop with things like Active Directory,ADO, COM+
services, CDO, OLEDB, OleTx, MSMG, DirectX and WMI to name a few, that's why
there are no System.DirectoryServices, System.EnterpriseServices,
System.Messaging, System.Data, System.Transactions, System.Drawing and
System.Management namespaces available in mono.
And don't get me started on the profiler, debugger and hosting services as
now available in V2, the hosting interfaces,just like the profiler and
debugger interfaces (COM) are needed to ease the interoperation between
unmanaged code and managed code. The unmanaged (again COM) hosting interface
is used by SQL Server 2005, and all serious debuggers and profilers are
written in unmanaged C/C++.


| > Also, don't believe that COM is going
| > away, it's just moving down from the user level to the system level,
Vista
| > has a lot more COM components added than there are .NET components.
Actually
| > Vista can run without .NET, but it can't without COM.
|
| Fine, I can live with that.
|
| > Note that I'm not talking about technologies built on top of COM (like
| > ActiveX, OLE etc), I'm talking about the low level COM binary interface
| > standard, which makes it possible for software components (whatever
| > language) to interoperate seamlessly using a well defined standard
| > interface.
| > Once you understand the COM interface definitions (the object model) and
| > it's rules, you'll better understand why/how things are working (or
| > fail).
|
| Hmm... unfortunately, in my limited experience things don't quite work
| as they're meant to. For instance, the way you expressed the use of COM
| in a previous message suggested that if I'm using a COM wrapper that
| requires an STA, it's more efficient to specify STAThread but that
| things should still work without, via marshalling. Well, thinking of
| the one time I've definitely had to use COM explicitly in C#, things
| didn't work at all without STAThread. (I can't remember the exact error
| message, unfortunately.) It could very well be that this was a badly
| written COM library, but my impression from messages I've read over the
| years is that there are more badly written bits of COM than well
| written ones...
|

The major problem with .NET is the fact that users start to run multiple
thread to create all kind of objects, without respecting some basic rules.
Two important rules that seems to be forgotten quite often, are:
- Windows UI elements have thread affinity, so don't touch them from another
thread than the creator's thread, and
- 'Apartment' threaded COM objects have STA thread affinity, and while COM
takes care of this, it's far better to arrange that your objects run on the
creator's STA thread, which is preferably the UI thread. If you don't take
care of this, you'll incur marshaling overhead, worse, if your objects
marshals to the COM default thread, make sure it's a pumping thread (like
the UI thread), or you will block the finalizer thread.
Note that you might have some issues with 'apartment' threaded objects in a
multi-threaded application, but once you follow some simple rules, they are
quite simple to use. Note also that most COM classes are 'both' threaded, so
they can live in an STA and an MTA. Some quite sophisticated COM objects are
thread neutral (just like CLR objects), and they don't need an apartment to
live in, but they are quite complex to author (correctly).

Honestly, take some time to learn the basics of COM, I'm sure you will like
it.

Willy.
 
J

Jon Skeet [C# MVP]

Willy Denoyette said:
| Quite a lot, IMO. Put it this way - I doubt that Mono on Linux uses
| COM, and it still manages to be useful. Java doesn't use COM (at least
| not on non-Windows platforms) and manages to achieve many of the same
| things as .NET. I don't see why COM is a necessary part of applications
| which don't appear to naturally require it.

True, but that's because Linux doesn't have COM. That means you don't need
to interop with existing COM servers (like the Office product suite,
Exchange server, a zillion of VB6 applications....).

Sure - but *I* personally don't need to do that either. That's my point
- I dare say a lot of other people need to use COM, but fortunately
that doesn't include me.
Believe me, without COM, .NET would have died before it was even
born, for the same reason why Java failed on the Windows client.

I don't think it would have *needed* to die - there's still a good
story in many respects without COM - but I agree that being *able* to
use COM from .NET is a good thing.
Nor does it have to interop with things like Active Directory,ADO, COM+
services, CDO, OLEDB, OleTx, MSMG, DirectX and WMI to name a few, that's why
there are no System.DirectoryServices, System.EnterpriseServices,
System.Messaging, System.Data, System.Transactions, System.Drawing and
System.Management namespaces available in mono.

The Mono project wishes to differ. Have a look at:
http://mono.ximian.com/class-status/mono-HEAD-vs-fx-2/index.html

Not everything is done by any means, but claiming there's *no* support
is inaccurate too. (Some of them are currently completely missing, but
I don't expect that to be the case forever.)

| Hmm... unfortunately, in my limited experience things don't quite work
| as they're meant to. For instance, the way you expressed the use of COM
| in a previous message suggested that if I'm using a COM wrapper that
| requires an STA, it's more efficient to specify STAThread but that
| things should still work without, via marshalling. Well, thinking of
| the one time I've definitely had to use COM explicitly in C#, things
| didn't work at all without STAThread. (I can't remember the exact error
| message, unfortunately.) It could very well be that this was a badly
| written COM library, but my impression from messages I've read over the
| years is that there are more badly written bits of COM than well
| written ones...

The major problem with .NET is the fact that users start to run multiple
thread to create all kind of objects, without respecting some basic rules.
Two important rules that seems to be forgotten quite often, are:
- Windows UI elements have thread affinity, so don't touch them from another
thread than the creator's thread, and
- 'Apartment' threaded COM objects have STA thread affinity, and while COM
takes care of this, it's far better to arrange that your objects run on the
creator's STA thread, which is preferably the UI thread. If you don't take
care of this, you'll incur marshaling overhead, worse, if your objects
marshals to the COM default thread, make sure it's a pumping thread (like
the UI thread), or you will block the finalizer thread.

Well, the app I was thinking of was single-threaded, and failed to even
find the interface without being explicitly an STA.
Note that you might have some issues with 'apartment' threaded objects in a
multi-threaded application, but once you follow some simple rules, they are
quite simple to use. Note also that most COM classes are 'both' threaded, so
they can live in an STA and an MTA. Some quite sophisticated COM objects are
thread neutral (just like CLR objects), and they don't need an apartment to
live in, but they are quite complex to author (correctly).

Honestly, take some time to learn the basics of COM, I'm sure you will like
it.

I've tried - admittedly when I was writing C++ at the time. I'll stick
with managed code wherever I can - it's a *lot* simpler. (The whole
idea of apartments is horrible IMO.)
 
W

Willy Denoyette [MVP]

| > | Quite a lot, IMO. Put it this way - I doubt that Mono on Linux uses
| > | COM, and it still manages to be useful. Java doesn't use COM (at least
| > | not on non-Windows platforms) and manages to achieve many of the same
| > | things as .NET. I don't see why COM is a necessary part of
applications
| > | which don't appear to naturally require it.
| >
| > True, but that's because Linux doesn't have COM. That means you don't
need
| > to interop with existing COM servers (like the Office product suite,
| > Exchange server, a zillion of VB6 applications....).
|
| Sure - but *I* personally don't need to do that either. That's my point
| - I dare say a lot of other people need to use COM, but fortunately
| that doesn't include me.
|
| > Believe me, without COM, .NET would have died before it was even
| > born, for the same reason why Java failed on the Windows client.
|
| I don't think it would have *needed* to die - there's still a good
| story in many respects without COM - but I agree that being *able* to
| use COM from .NET is a good thing.
|
| > Nor does it have to interop with things like Active Directory,ADO, COM+
| > services, CDO, OLEDB, OleTx, MSMG, DirectX and WMI to name a few, that's
why
| > there are no System.DirectoryServices, System.EnterpriseServices,
| > System.Messaging, System.Data, System.Transactions, System.Drawing and
| > System.Management namespaces available in mono.
|
| The Mono project wishes to differ. Have a look at:
| http://mono.ximian.com/class-status/mono-HEAD-vs-fx-2/index.html
|
| Not everything is done by any means, but claiming there's *no* support
| is inaccurate too. (Some of them are currently completely missing, but
| I don't expect that to be the case forever.)
|

None of them I mentioned are complete in a sense that they are usable,
sorry. If you are a corporate user (some of the larger accounts we have are
experimenting, but until now none did seriousy consider mono btw.), you want
a complete solution not something that is implemented partly. One account
I'm consulting is experimenting with mono in a distributed application, to
our surprise the base class ServicedComponent is only 53% finished, now
where does this lead us? Unfortunately, nowhere, no implementation of
Activate, Deactivate, Dispose etc. That means no support for pooled
components, the same goes for ContextUtil, that means no transaction
support. In the same context whe started to look at the DirectoryServices
namespace, same story here, there isn't even a possibility to connect to AD
using explicit credentials. Currently I'm looking into System.Management to
see what we can do on Linux at the management level, same story here, 'the'
baseclass ManagementBaseObject is not usable, the ManagementClass is missing
completely, no possibility to connect to remote systems, no support for
management events.....
I didn't use the System.Data namespace, but IMO the story is the same, too
many features missing or not working.



|
| > | Hmm... unfortunately, in my limited experience things don't quite work
| > | as they're meant to. For instance, the way you expressed the use of
COM
| > | in a previous message suggested that if I'm using a COM wrapper that
| > | requires an STA, it's more efficient to specify STAThread but that
| > | things should still work without, via marshalling. Well, thinking of
| > | the one time I've definitely had to use COM explicitly in C#, things
| > | didn't work at all without STAThread. (I can't remember the exact
error
| > | message, unfortunately.) It could very well be that this was a badly
| > | written COM library, but my impression from messages I've read over
the
| > | years is that there are more badly written bits of COM than well
| > | written ones...
| >
| > The major problem with .NET is the fact that users start to run multiple
| > thread to create all kind of objects, without respecting some basic
rules.
| > Two important rules that seems to be forgotten quite often, are:
| > - Windows UI elements have thread affinity, so don't touch them from
another
| > thread than the creator's thread, and
| > - 'Apartment' threaded COM objects have STA thread affinity, and while
COM
| > takes care of this, it's far better to arrange that your objects run on
the
| > creator's STA thread, which is preferably the UI thread. If you don't
take
| > care of this, you'll incur marshaling overhead, worse, if your objects
| > marshals to the COM default thread, make sure it's a pumping thread
(like
| > the UI thread), or you will block the finalizer thread.
|
| Well, the app I was thinking of was single-threaded, and failed to even
| find the interface without being explicitly an STA.
|

I'm sure you know that a single-threaded application doesn't exists in .NET,
so you don't consider the threads created by the CLR (like the finalizer
thread) other than the main thread.
Now back to the problem you had.
An application that creates an 'apartment' threaded object (implicitely or
explicitely) in a non STA (your main) thread, turns into a multithreaded
application.
COM needs an STA to run the component, so it creates a background OS thread
that enters an STA, and returns a reference to a proxy to your main thread,
which enters the MTA (every thread that holds a reference to a COM interface
must be in an apartment, the CLR takes care of this).

So now you have three threads (I don't consider the debugger helper thread):
1 Main MTA
2 Finalizer MTA
3 COM default STA
So you see that your calls into the COM object must be marshaled from 1 to 2
using windows message passing (the same is done when marshaling delegates
from non UI to the UI thread), note that this is taken care of by COM. But
here is the problem, the STA thread has a message queue, but it doesn't pump
the queue, that means that the first call, which, as a result of a cast, is
a QueryInterface call, never gets processed unless the object itself
correctly pumps the queue. The QI returns after a time-out with a failure
code that gets translated into an exception.
Another problem, is that the finalizer thread (MTA) will block whenever he
needs to finalize the RCW.

Now, you could ask - why is COM spawning a thread that enters the STA while
it doesn't pump it's queue, well the answer is that this is done to
accomodate 'single' threaded COM objects (as created by VB4) which do have
the necessary pumping code as part of their implementation.
Conclusion, if you need to create 'apartment' threaded objects, make sure
your thread is initialized as STA, if they are 'both' or 'free' threaded,
prefer an MTA for best performance.
If your COM ojects are 'single' threaded, don't use them in .NET, go back to
VB.



| > Note that you might have some issues with 'apartment' threaded objects
in a
| > multi-threaded application, but once you follow some simple rules, they
are
| > quite simple to use. Note also that most COM classes are 'both'
threaded, so
| > they can live in an STA and an MTA. Some quite sophisticated COM objects
are
| > thread neutral (just like CLR objects), and they don't need an apartment
to
| > live in, but they are quite complex to author (correctly).
| >
| > Honestly, take some time to learn the basics of COM, I'm sure you will
like
| > it.
|
| I've tried - admittedly when I was writing C++ at the time. I'll stick
| with managed code wherever I can - it's a *lot* simpler. (The whole
| idea of apartments is horrible IMO.)
|

I have to disagree, I had the same impression when I started with .NET back
in 2000, but in the meantime I changed my mind, both are equally complex,
both are equally simple at the surface.
The apartments idea is an elegant solution when you need to use thread
unaware (unsafe) components (mainly VB but also C++) in a threaded
application.
Tools like C++, are available to author 'free' and thread 'neutral' objects,
but this comes at a prices !! complexity !!, the components themselves must
be thread safe, and this price is the same (IMO) whether you author CLR
components using a managed language or COM coponents using C++.
A lot of the threaded CLR based components I tested/debugged the recent
years where buggy, at the surface they look OK, they passed extended unit
tests on low-end boxes, but a lot of them failed when stressed on high-end
boxes with 4 or more CPU's. Lets face it, writing correct MT applications is
hard, writing MT components is much harder.

Willy.
 
J

Jon Skeet [C# MVP]

Willy Denoyette [MVP] wrote:

Conclusion, if you need to create 'apartment' threaded objects, make sure
your thread is initialized as STA, if they are 'both' or 'free' threaded,
prefer an MTA for best performance.
If your COM ojects are 'single' threaded, don't use them in .NET, go back to
VB.

And that's where we seem to be a far cry from a comment from your
original post:
"but it works, that's the beauty of COM."

The impression you gave in that post was that if you don't understand
all the details, you might end up with a suboptimal solution, but it
will still work. The bit I've quoted at the top of this post seems much
more like reality - you *do* need to know details about what the COM
objects you're using are doing, what their preferred environment is
etc.

I fully agree that writing thread-safe components is hard - but I
disagree that the best way to work around that is to do all this
marshalling. It doesn't remove the complexity, it just shifts it
around.

Maybe I'll like COM one day - but I doubt it.

Jon
 
K

Kalpesh

Guys,

This is an interesting conversation.
William, can you explain to a VB6 developer - what is the idea of
apartment?
what is STA, MTA & theory behind marshalling?

Being a VB developer, this concepts are alien to me

Thanks
Kalpesh
 
W

Willy Denoyette [MVP]

| Willy Denoyette [MVP] wrote:
|
| <snip>
|
| > Conclusion, if you need to create 'apartment' threaded objects, make
sure
| > your thread is initialized as STA, if they are 'both' or 'free'
threaded,
| > prefer an MTA for best performance.
| > If your COM ojects are 'single' threaded, don't use them in .NET, go
back to
| > VB.
|
| And that's where we seem to be a far cry from a comment from your
| original post:
| "but it works, that's the beauty of COM."
|
No it's not, it works, but you need to respect some simple rules of COM,
just like you need to respect many rules when using .NET components or Java
components whatever.
If you need to create 'apartment' type objects, make sure you have a pumping
STA thread in your process (it doesn't have to be the creator's thread), it
will always work. If your object ends on the COM created thread it will fail
if it's 'apartment' threaded, it will work for all other types.
Otherwise stated, 'apartment' threaded objects are best used in UI based
applications, where the UI thread is a pumping STA thread,
Other kind of objects like 'Free','Both' and 'Neutral' always work in server
based applications, they don't need an STA thread. If you need to use STA
based objects in 'server' like application (console, services..), you need a
pumping STA thread in the process and for best performance this should also
be the creators thread, if you forget this things will go wrong.

| The impression you gave in that post was that if you don't understand
| all the details, you might end up with a suboptimal solution, but it
| will still work. The bit I've quoted at the top of this post seems much
| more like reality - you *do* need to know details about what the COM
| objects you're using are doing, what their preferred environment is
| etc.
|

Yep, but it's not that difficult to remember the basic rules, if you care,
but I guess that's your problem, you don't care (or should I say don't like)
about COM.

| I fully agree that writing thread-safe components is hard - but I
| disagree that the best way to work around that is to do all this
| marshalling. It doesn't remove the complexity, it just shifts it
| around.
|
It shifts it to the system level, where it belongs, and it's rock solid
after the years. The same thing happens in the CLR which takes care of a lot
of the complexities inherent to an extensible and distributed object model
(see AD marshaling, thread pooling, memory management etc..).
But again, you seem to forget that you can simply eliminate the marshaling
completely when taking care about the simple apartment rules I mentioned
before. Note that many components were designed to be used in UI type of
applications (VB6, MFC), the "server" types are (in principle) thread safe
and can be used in the MTA. If you use an 'apartment' type component in a
non-UI style application, then you need to know what you are doing and
respect some rules, just like you need to respect a lot of rules when using
thread-unsafe managed objects in .NET. Note that I only talk about using,
not authoring thread-safe objects( COM or other).


| Maybe I'll like COM one day - but I doubt it.

I doubt it also, IMO you are not open for it ;-) but you are missing a lot.

Willy.
 
W

Willy Denoyette [MVP]

| Guys,
|
| This is an interesting conversation.
| William, can you explain to a VB6 developer - what is the idea of
| apartment?
| what is STA, MTA & theory behind marshalling?
|
| Being a VB developer, this concepts are alien to me
|
| Thanks
| Kalpesh
|

Well, it's not that easy to explain in a few words, but if you are willing
to spend some time to know more about Apartment types, COM Context and
synchronization boundaries, take a look at this:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncomser/html/comthread.asp
and
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncomser/html/comthread.asp
and
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncomser/html/comthread.asp

but beware, don't try to understand all at once, take your time and start
with the basics.

Willy.
 
J

Jon Skeet [C# MVP]

Willy said:
| And that's where we seem to be a far cry from a comment from your
| original post:
| "but it works, that's the beauty of COM."
No it's not, it works, but you need to respect some simple rules of COM,
just like you need to respect many rules when using .NET components or Java
components whatever.

And that's okay - I guess I just don't think it's *quite* as
straightforward as you made it out to be.

Of course, it could well be that I've been using misbehaving COM
components. Given how foul the interface was, I wouldn't be at all
surprised.
Yep, but it's not that difficult to remember the basic rules, if you care,
but I guess that's your problem, you don't care (or should I say don't like)
about COM.

The details are slightly hazy at the moment, but when I was trying to
use COM from C++, I remember reading about such rules and what would
supposedly happen automatically for a long time, and finding the whole
thing immensely frustrating. Things which *should* have worked just
didn't. .NET made the whole thing a lot easier, I'll readily admit that
- but there were still issues.

If I ever need to work with COM (knowingly) again, I'll dig a bit
deeper (you know I like understanding what I'm doing) - but until I've
got a reason to look at it, it's not something I'm going to spend spare
time looking into.

Jon
 

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