Re: STAThread vs non STAThread framework
- From: Jon Skeet [C# MVP] <skeet@xxxxxxxxx>
- Date: Mon, 22 Oct 2007 10:59:38 +0100
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
.
- Follow-Ups:
- Re: STAThread vs non STAThread framework
- From: Willy Denoyette [MVP]
- Re: STAThread vs non STAThread framework
- References:
- STAThread vs non STAThread framework
- From: rafalK
- Re: STAThread vs non STAThread framework
- From: Willy Denoyette [MVP]
- Re: STAThread vs non STAThread framework
- From: Jon Skeet [C# MVP]
- Re: STAThread vs non STAThread framework
- From: Willy Denoyette [MVP]
- STAThread vs non STAThread framework
- Prev by Date: Re: C# 3.0 and KB908002
- Next by Date: Re: C# 3.0 and KB908002
- Previous by thread: Re: STAThread vs non STAThread framework
- Next by thread: Re: STAThread vs non STAThread framework
- Index(es):
Relevant Pages
|
Loading