Thursday, March 22, 2012

WaitAll for multiple handles on an STA thread is not supported

Our system app is throwing this error intermittantly. I've seen a few
cases of it in the groups, but they all seem to apply to calling
WaitHandler.WaitAll from the UI thread in a WinForms app, which isn't
what we're doing.
We have our main web app running on one server. It creates and makes a
call to an object running on another server, via remoting. That object
creates a delegate to a private method, uses BeginInvoke on the
delegate, then returns control to the web app.
The private method that was called asynchronously does some work then
makes several parallel calls to a third component (again by using
delegates and BeginInvoke) which lives on a third server and is again
accessed via remoting. Once all of the calls have been made, with the
resultant WaitHandles stored in an array, WaitHandler.WaitAll is
called.
Sometimes at this point an error is thrown with the description
"WaitAll for multiple handles on an STA thread is not supported".
The remoted objects are both hosted in IIS running on Windows 2000.
Any ideas?
The first remote object (being called from the web app) shares a server
with another component. This is also accessed via remoting but is
hosted in a separate IIS app. This second component accesses unmanaged
code in a C++ DLL (not a COM DLL). Could this have something to do with
it, and if so how?
Help!
Thanks,
JonDo you have an pages marked with AspCompat=true ?
I'd zero in and inspect those pages - they will use an STA thread.
Scott
http://www.OdeToCode.com/blogs/scott/
On 5 Sep 2005 00:26:43 -0700, jon.george1@.gmail.com wrote:

>Our system app is throwing this error intermittantly. I've seen a few
>cases of it in the groups, but they all seem to apply to calling
>WaitHandler.WaitAll from the UI thread in a WinForms app, which isn't
>what we're doing.
>We have our main web app running on one server. It creates and makes a
>call to an object running on another server, via remoting. That object
>creates a delegate to a private method, uses BeginInvoke on the
>delegate, then returns control to the web app.
>The private method that was called asynchronously does some work then
>makes several parallel calls to a third component (again by using
>delegates and BeginInvoke) which lives on a third server and is again
>accessed via remoting. Once all of the calls have been made, with the
>resultant WaitHandles stored in an array, WaitHandler.WaitAll is
>called.
>Sometimes at this point an error is thrown with the description
>"WaitAll for multiple handles on an STA thread is not supported".
>The remoted objects are both hosted in IIS running on Windows 2000.
>Any ideas?
>The first remote object (being called from the web app) shares a server
>with another component. This is also accessed via remoting but is
>hosted in a separate IIS app. This second component accesses unmanaged
>code in a C++ DLL (not a COM DLL). Could this have something to do with
>it, and if so how?
>Help!
>Thanks,
>Jon
If you ever do any blocking on a STA thread you should use the Win32 functio
n
MsgWaitForMultipleObjects. If you're running on STA in your managed code
WaitHandle.WaitAll does not use this API and thus the exception. The answer
is to not call WaitHandle.WaitAll if you're on STA thread. Why do you have
an STA thread in your app?
-Brock
DevelopMentor
http://staff.develop.com/ballen

> Our system app is throwing this error intermittantly. I've seen a few
> cases of it in the groups, but they all seem to apply to calling
> WaitHandler.WaitAll from the UI thread in a WinForms app, which isn't
> what we're doing.
> We have our main web app running on one server. It creates and makes a
> call to an object running on another server, via remoting. That object
> creates a delegate to a private method, uses BeginInvoke on the
> delegate, then returns control to the web app.
> The private method that was called asynchronously does some work then
> makes several parallel calls to a third component (again by using
> delegates and BeginInvoke) which lives on a third server and is again
> accessed via remoting. Once all of the calls have been made, with the
> resultant WaitHandles stored in an array, WaitHandler.WaitAll is
> called.
> Sometimes at this point an error is thrown with the description
> "WaitAll for multiple handles on an STA thread is not supported".
> The remoted objects are both hosted in IIS running on Windows 2000.
> Any ideas?
> The first remote object (being called from the web app) shares a
> server with another component. This is also accessed via remoting but
> is hosted in a separate IIS app. This second component accesses
> unmanaged code in a C++ DLL (not a COM DLL). Could this have something
> to do with it, and if so how?
> Help!
> Thanks,
> Jon
>> Why do you have an STA thread in your app?
That's kind of the question!
We've searched through the code for pages marked with AspCompat=true,
as well as any unexpected use of [STAThread] and come up with nothing.
However, we have discovered that the unmanaged code used by a remoting
object hosted in a separate IIS web app is using the MS XML parser. The
theory at the moment is that when this is running it is forcing threads
into STA mode. Due to the fact that there is a thread pool shared by
both web apps, the app we are having the problem with is ending up with
threads that are in STA mode.
Although I would have initially though that this wasn't possible, it's
the only place where any of our .NET code has anything to do with a COM
object, albeit indirectly.
Thoughts/ideas welcome!
Thanks for the responses so far.
Jon
So somehow a thread in your threadpool is getting marked as STA. This could
happen as a result of code calling into a COM component that's marked as
Apartment in the registry. This will set your thread's apartment to STA if
it's not already been set. I would try to isolate the code that calls into
the COM component. Try it in a test app (like a console app) and make a call
into it then check System.Threading.Thread.CurrentThread.ApartmentState afte
r
the class and see if it's getting set to STA. If it is, then then there's
your answer. If that's the case, then I'd suggest managing some seperate
threads (not in the threadpool) to call into the COM component because you
don't want the threadpool thread to accidently get into an STA.
The dreaded COM threading model has come back to haunt you! Heh, GL.
-Brock
DevelopMentor
http://staff.develop.com/ballen

> That's kind of the question!
> We've searched through the code for pages marked with AspCompat=true,
> as well as any unexpected use of [STAThread] and come up with nothing.
> However, we have discovered that the unmanaged code used by a remoting
> object hosted in a separate IIS web app is using the MS XML parser.
> The theory at the moment is that when this is running it is forcing
> threads into STA mode. Due to the fact that there is a thread pool
> shared by both web apps, the app we are having the problem with is
> ending up with threads that are in STA mode.
> Although I would have initially though that this wasn't possible, it's
> the only place where any of our .NET code has anything to do with a
> COM object, albeit indirectly.
> Thoughts/ideas welcome!
> Thanks for the responses so far.
> Jon
>
That would certainly match up with what we are seeing, and is the
assumption we have been working on. However, we weren't actually sure
if a) it was possible or b) why the CLR would casually allocate threads
regardless of their current apartment state!
We've been told by MS that marking the methods we invoke asynchronously
with the [MTAThread] attribute should solve the problem, so we'll try
this first (as it's less effort). If it doesn't work, then your
suggestion will probably be the next course of action.
Thanks again.
Jon

0 comments:

Post a Comment