Re: STAThread vs non STAThread framework



Willy Denoyette [MVP] <willy.denoyette@xxxxxxxxxx> wrote:
Out of interest, what are the problems one might find without this? For
test purposes I've often created forms which do very little, and rarely
bothered to put the STAThread attribute on them. They've been fine -
but I quite understand that either this was through chance or because I
wasn't using particular components.

A couple of the Windows Forms controls are simple wrappers around ActiveX
COM controls, notably all the "Dialog Controls" are AX control wrappers, one
of them being the OpenFileDialog as used by the OP.
Such controls need a *pumping* STA thread to run on.

Right. Okay, so in many cases you'd get away with it not entirely
through chance but just by not using the controls which require the
pumping STA.

Now, if you don't initialize your UI thread to enter an STA, the CLR will
initialize the thread to enter the MTA whenever you call into COM for the
first time, that is when you create an instance of say OpenFileDialog. Note
that the v2 SP1 CLR initializes the thread to enter the MTA (if not marked
otherwise) even before it starts the main thread.

Yikes - that sounds like a significant change. My understanding was
that the CLR would only initialize a thread one way or another the
first time a method with STAThread or MTAThread was encountered on that
thread. In other words, your Main method could call something else
which in turn was decorated with STAThread. Am I right in interpreting
your comments to say this isn't the case with the v2 CLR SP1?

FileDialog (the wrapped AX dialog) as all other dialogs, is marked as
requiring an STA, so it can't get instantiated on the calling MTA thread,
COM takes care of this by creating a new thread that gets initialized to
enter an STA and creates the instance of the dialog on this thread and
returns a proxy to the caller.
That mean you'll end with the following (important for this discussion)
threads in a Forms application that doesn't mark it's main UI thread as
STAThread.

Main thread (UI) MTA.
GDI Thread MTA (used by Forms)
STA thread created by COM hosting the FileDialog AX control.

Why is the GDI thread not the main thread? I thought that
Application.Run just ran the message pump on the current thread? Or
does GDI just need two threads anyway, one for message pumping and one
for something else?

So far so good, the control runs on a compatible thread, and the caller
receives a proxy (a marshaled Interface Pointer). The problem however is
that the STA thread created by COM on your behalf isn't pumping messages,
that means that your OpenFileDialog cannot communicate with the callers
thread. The result is that the dialog cannot be used,it will not even
show-up (I guess) and the UI thread deadlocks.
Note also that the Finalizer (MTA) thread cannot access the controls STA
thread whenever he needs to run the Control's Finalize method. This is no
big deal in this scenario, as the control is non-functional anyway, but it's
a big issue when you have to deal with non-visual AX controls.

Right. Thanks for clearing that up. Admittedly it's open up other cans
of worms in terms of my understanding of WinForms, but there we go...

--
Jon Skeet - <skeet@xxxxxxxxx>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
.



Relevant Pages

  • Re: STAThread vs non STAThread framework
    ... > bothered to put the STAThread attribute on them. ... A couple of the Windows Forms controls are simple wrappers around ActiveX ... initialize the thread to enter the MTA whenever you call into COM for the ... that the v2 SP1 CLR initializes the thread to enter the MTA (if not marked ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: STAThread vs non STAThread framework
    ... If you only use controls that are *not* COM based, ... so STATHread is a safe bet when you have to deal with Forms ... attribute, the RCW will initialize the thread to enter the MTA, else it will ... STAThread initializes the thread to enter an STA, ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Service hangs when accessing ActiveX control
    ... > in an MTA by default, if this is not what you want, you have to create your ... Not specifying any attribute or specifying it as STA results in the same ... service and the default is STAThread. ... > requirements as AX controls. ...
    (microsoft.public.dotnet.framework.interop)
  • Re: OLE call STAThreadAttribute exeception on saveFileDialog.ShowDialog(this)
    ... although mainhas [STAThread] attribute, ... form application changed to MTA mode. ... a backgroud process that does the work to be able to update a progress ... You could do the easier thing and change the attribute to STA.. ...
    (microsoft.public.dotnet.framework)
  • Re: i want to run my app in STA, not MTA
    ... How would I go about making sure my C# 2.0 app runs under STA, not MTA? ... [STAThread] ...
    (microsoft.public.dotnet.languages.csharp)

Loading