Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / March 2008

Tip: Looking for answers? Try searching our database.

Not using [STAThread]

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
K Viltersten - 15 Mar 2008 20:51 GMT
I see that VS by default pops in the
statement [STAThread] in the code and since
i started with all-blank-project this time,
the part was missing.

Nevertheless, the program works and is
happy. So i wonder - what's that good for?

Is it something internal for VS or is it a
part of C#?

--
Regards
Konrad Viltersten
--------------------------------
sleep    - a substitute for coffee for the poor
ambition - lack of sense to be lazy
Arne Vajhøj - 15 Mar 2008 21:00 GMT
> I see that VS by default pops in the
> statement [STAThread] in the code and since
[quoted text clipped - 5 lines]
> Is it something internal for VS or is it a
> part of C#?

http://blogs.msdn.com/jfoscoding/archive/2005/04/07/406341.aspx
http://www.sellsbrothers.com/askthewonk/Secure/WhatdoestheSTAThreadattri.htm
http://www.codeguru.com/forum/showthread.php?t=407960
etc.

Arne
Peter Duniho - 15 Mar 2008 21:06 GMT
> I see that VS by default pops in the
> statement [STAThread] in the code and since
[quoted text clipped - 5 lines]
> Is it something internal for VS or is it a
> part of C#?

It's related to .NET and how it uses COM.  It signals to the compiler to  
cause the thread executing that method (Main(), in the case of the VS  
templates) to be initialize itself as a "single-threaded apartment" thread.

If the thread never actually uses COM, then you don't need it.  You don't  
describe any details about your project, so whether it's a bug to not  
include that attribute (not statement) in your code, I can't say.  For a  
Forms-based Windows application though, it should be there.  For a console  
application, it's not necessarily needed.

Pete
K Viltersten - 15 Mar 2008 21:21 GMT
>> I see that VS by default pops in the
>> statement [STAThread] in the code and since
[quoted text clipped - 16 lines]
> Forms-based Windows application though, it should be there.  For a console
> application, it's not necessarily needed.

Thanks to both. Yes, i'm doing the console this time,
so it's probably the reason. Nevertheless, i'll put it in,
just for the sake of future sanity.   :)

Signature

--
Regards
Konrad Viltersten
--------------------------------
sleep    - a substitute for coffee for the poor
ambition - lack of sense to be lazy

Peter Duniho - 15 Mar 2008 23:24 GMT
> Thanks to both. Yes, i'm doing the console this time,
> so it's probably the reason. Nevertheless, i'll put it in,
> just for the sake of future sanity.   :)

I wouldn't, if I were you.  AFAIK, a normal console application never  
actually has to initialize COM.  By putting that attribute in, you cause  
COM to be initialized.  At a minimum, this is a waste.  Additionally,  
doing so in a console application could interfere with garbage collection  
(I just found this doing a search on MSDN:  
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=16154&SiteID=1).

Basically, unless you have a specific need to explicitly specify the  
apartment model, don't.

Pete
K Viltersten - 15 Mar 2008 23:38 GMT
>> Thanks to both. Yes, i'm doing the console this time,
>> so it's probably the reason. Nevertheless, i'll put it in,
[quoted text clipped - 8 lines]
>Basically, unless you have a specific need to explicitly specify the
>apartment model, don't.

Great info. Thanks!

--
Regards
Konrad Viltersten
--------------------------------
sleep    - a substitute for coffee for the poor
ambition - lack of sense to be lazy
Jon Skeet [C# MVP] - 15 Mar 2008 23:41 GMT
> > Thanks to both. Yes, i'm doing the console this time,
> > so it's probably the reason. Nevertheless, i'll put it in,
[quoted text clipped - 3 lines]
> actually has to initialize COM.  By putting that attribute in, you cause
> COM to be initialized.

Are you sure? I thought it just initialized the thread in a way which
allowed STA COM components to be used later. I've certainly used it in
the past with no ill effects.

>  At a minimum, this is a waste.  Additionally,
> doing so in a console application could interfere with garbage collection
> (I just found this doing a search on MSDN:
> http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=16154&SiteID=1).

It sounds like in that case there *was* COM involved though.

> Basically, unless you have a specific need to explicitly specify the
> apartment model, don't.

I guess the only worry is if you really don't know whether the
underlying .NET code is going to use COM at some point. I think this is
a significant problem - it's really not terribly obvious which APIs
beyond some (but not all?) WinForm controls use COM under the hood.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk

Peter Duniho - 16 Mar 2008 00:40 GMT
>> I wouldn't, if I were you.  AFAIK, a normal console application never
>> actually has to initialize COM.  By putting that attribute in, you cause
[quoted text clipped - 3 lines]
> allowed STA COM components to be used later. I've certainly used it in
> the past with no ill effects.

Am I sure?  No...that's why I wrote "AFAIK" (i.e. "as far as I know").  
However, normally the way you initialize a thread's apartment state is to  
pass the appropriate flag, either COINIT_APARTMENTTHREADED or  
COINIT_MULTITHREADED, when calling CoInitializeEx().

If the .NET is somehow using that attribute to turn it into a call to  
CoInitializeEx() (and I would expect it to), then using the attribute  
would thus imply an initialization of COM.

>>  At a minimum, this is a waste.  Additionally,
>> doing so in a console application could interfere with garbage  
[quoted text clipped - 3 lines]
>
> It sounds like in that case there *was* COM involved though.

Right.  My reading of the post is that the leak happened because COM was  
involved and being used inappropriately.  The point here is that the OP is  
suggesting that he'll put that attribute in now, "just in case", but in  
fact if and when it actually becomes relevant, it could actually _hurt_ to  
have a single-threaded apartment rather than help.

In other words, at the time that the attribute becomes relevant, the OP  
had better be making a conscious decision about which apartment model to  
use and given that, they will have every opportunity to add the correct  
attribute at that time.  Until that time, it isn't adding anything useful,  
and could very well lead to loading COM into the process when it wasn't  
necessary.

For what it's worth, I ran a quick test, modifying an existing console  
application I had lying around by adding the [STAThread] attribute to the  
Main() method.  Comparing the loaded DLL's for the process between the two  
instances, the one with the attribute had three extra DLLs: MSCTF.DLL,  
UXTHEME.DLL, and PRLHOOK.DLL.  The last one is particular to my Windows  
installation (the description is "Parallels Helper Hook", so presumably it  
got loaded as a side-effect of one of the other DLLs and because I'm  
running Windows in a VM), but I'd guess the other two would show up on  
anyone's computer.

I admit, even after some quick Googling, I don't have an explanation for  
_why_ those particular DLLs get sucked in when STAThread is specified.  
They don't seem directly related to COM per se.  But I can confirm there's  
a definite difference in how the process executes even if all you've done  
is add that attribute.

So, again: I would not add it until such point in time if and when it is  
actually needed.  It's not going to help anything, and it could be  
detrimental.

Pete
Jon Skeet [C# MVP] - 16 Mar 2008 08:29 GMT
> >> I wouldn't, if I were you.  AFAIK, a normal console application never
> >> actually has to initialize COM.  By putting that attribute in, you cause
[quoted text clipped - 5 lines]
>
> Am I sure?  No...that's why I wrote "AFAIK" (i.e. "as far as I know").

Well, to be picky that was in the sentence saying that you didn't have
to initialize COM - the following sentence sounded more confident :)

> However, normally the way you initialize a thread's apartment state is to
> pass the appropriate flag, either COINIT_APARTMENTTHREADED or
[quoted text clipped - 3 lines]
> CoInitializeEx() (and I would expect it to), then using the attribute
> would thus imply an initialization of COM.

Interestingly, the docs for STAThreadAttribute say:

<quote>

> >>  At a minimum, this is a waste.  Additionally,
> >> doing so in a console application could interfere with garbage
[quoted text clipped - 38 lines]
>
> Pete

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk

Jon Skeet [C# MVP] - 16 Mar 2008 08:35 GMT
(Apologies if the first bit of this comes through twice.)

> >> I wouldn't, if I were you.  AFAIK, a normal console application never
> >> actually has to initialize COM.  By putting that attribute in, you cause
[quoted text clipped - 5 lines]
>
> Am I sure?  No...that's why I wrote "AFAIK" (i.e. "as far as I know").

Well, to be picky that was in the sentence saying that you didn't have
to initialize COM - the following sentence sounded more confident :)

> However, normally the way you initialize a thread's apartment state is to
> pass the appropriate flag, either COINIT_APARTMENTTHREADED or
[quoted text clipped - 3 lines]
> CoInitializeEx() (and I would expect it to), then using the attribute
> would thus imply an initialization of COM.

Interestingly, the docs for STAThreadAttribute say:

<quote>
The COM threading model can be set to single-threaded apartment or
multithreaded apartment. The application thread is only initialized for
COM interop if the thread actually makes a call to a COM component. If
COM interop is not used, then the thread is not initialized.
</quote>

(I hadn't seen that before this post, btw.)

I *hope* it's accurate, but you never know...

> >>  At a minimum, this is a waste.  Additionally,
> >> doing so in a console application could interfere with garbage
[quoted text clipped - 9 lines]
> fact if and when it actually becomes relevant, it could actually _hurt_ to
> have a single-threaded apartment rather than help.

Yes, that's true. Just to be clear though, I think we both agree that
it's not going to hurt garbage collection when COM *isn't* involved.

> In other words, at the time that the attribute becomes relevant, the OP
> had better be making a conscious decision about which apartment model to
> use and given that, they will have every opportunity to add the correct
> attribute at that time.  Until that time, it isn't adding anything useful,
> and could very well lead to loading COM into the process when it wasn't
> necessary.

That's reasonable. There's still the issue of what happens when COM
unwittingly gets dragged in - but that will be an issue either way.

<snip dll stuff, purely because I don't have anything to say about it>

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk

Peter Duniho - 16 Mar 2008 09:21 GMT
> Interestingly, the docs for STAThreadAttribute say:
>
[quoted text clipped - 8 lines]
>
> I *hope* it's accurate, but you never know...

Sure, I'd hope it's accurate too.  But I've seen too many inaccurate  
statements in the docs to be confident that it is.

Especially since when I compared two different console applications, the  
only difference between the two being the presence of the STAThread  
attribute in one, and saw that the one with the STAThread attribute does  
in fact load additional DLLs, I become somewhat more confident that I  
can't trust MSDN on this one.

I don't have a good explanation for why the particular DLLs that got  
loaded did in fact get loaded.  But I know for sure that they did, and I  
know for sure that it's a stable behavior (that is, add the attribute,  
they show up, remove the attribute, they go away).

Even if the behavior was different on someone else's computer, it's clear  
to me that that attribute is doing more, even when COM isn't explicitly  
involved, than just setting some flag in the managed thread for the COM  
interop to look at if it ever gets invoked.

Something is _executing_ differently, even when COM isn't used (or else it  
turns out that there's no such thing as a .NET console application that  
doesn't use COM...all I know is the console application was a trivial  
"print this float" program, and for all I know .NET _is_ in fact using COM  
for some reason, but if so that's even more reason to be concerned, since  
it means COM gets used implicitly for the most trivial programs).

> Yes, that's true. Just to be clear though, I think we both agree that
> it's not going to hurt garbage collection when COM *isn't* involved.

Well, I do agree with that statement.  The problem is, though, that I  
can't qualify "involved" with "explicitly".  My experiment shows me that  
something different happens with that attribute.  It _might_ be that COM  
gets used implicitly, in which case there could still be a garbage  
collection issue.  Or it could just be that .NET is loading extra DLLs  
without actually using COM past that point, in which case I think it's  
likely that wouldn't cause the GC issue to show up.

But I don't have any practical way to know the difference.  I mean, if I  
really cared I suppose I could research this and track down the actual  
answer.  But I don't, especially since I think there's already other good  
reasons to leave off the attribute unless it's actually needed.  So I just  
put that data in the "one more reason not to include the attribute"  
column.  :)

Pete
Willy Denoyette [MVP] - 16 Mar 2008 12:47 GMT
> (Apologies if the first bit of this comes through twice.)
>
[quoted text clipped - 32 lines]
>
> I *hope* it's accurate, but you never know...

Well, it's not accurate a all.
Actually, when  the (STA/MTA) attribute is set on Main, then COM gets
initialized *before* entering main, that is, ole32!CoInitializeEx is called
by the CLR before it enters managed code.
When the attribute is not set, and the thread is not initialized explicitly
, then the CLR will initialize the thread to join the MTA when calling into
COM for the first time.

To resume:
You have to set the STA/MTA attribute whenever you want to force your main
thread (your program's entry point) to run in a compatible apartment.
Calling into COM from a compatible apartment is the most effective way to
call into COM, as there is no need to marshal the calls across incompatible
apartments.
For Windows Forms, the compatible apartment is STA, the reason for this is
that WF needs an STA for drag/drop functionality and because a number of
controls are COM based and need an STA apartment to function properly

A console application doesn't need the attribute, unless it explicitly calls
into COM from it's main thread.
A console application that sets it's main thread to enter an STA, must pump
a message queue. This is not only a .NET requirement (finalizer thread),
it's a general COM requirement.
A console application that sets it's main thread to enter the MTA, does not
need a message pump.

Willy.

>> >>  At a minimum, this is a waste.  Additionally,
>> >> doing so in a console application could interfere with garbage
[quoted text clipped - 27 lines]
>
> <snip dll stuff, purely because I don't have anything to say about it>
Jon Skeet [C# MVP] - 16 Mar 2008 13:26 GMT
<snip>

> Well, it's not accurate a all.

Thanks for clearing up the confusion. I was kinda hoping you'd step in
at some point as resident COM expert :)

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk

Willy Denoyette [MVP] - 16 Mar 2008 16:26 GMT
> <snip>
>
>> Well, it's not accurate a all.
>
> Thanks for clearing up the confusion. I was kinda hoping you'd step in
> at some point as resident COM expert :)

The problem is that once you start to document "implementation details", you
also need to update the docs whenever *the* implementation changes. In this
particular case the docs were not updated after V1.1 changed the point where
COM was initialized. In general (and in this case), this is a non-issue,
such changes do not affect your code, but there may be others.....

Willy.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.