Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


STA Comes Not from STAbility

Microsoft proclaims VB 6 and STA components as stable enterprise architecture for the middle tier. On the other hand you can find lots of strong restrictions for STA under COM+. You should learn all the restrictions as well as investigate their real reasons and possible effects before picking out some particular architecture. This time the author helps you to study a piece of Microsoft day-to-day advice "Don't make blocking calls from STA."

continue a good cause started by Jimmy Nilsson saying "Don't you hate being told what to do and not to do, without knowing the reason why?" As for now the time has come to STA, the only apartment model available from VB 6 and formers. On the one hand Microsoft proclaims VB 6 and STA components as stable enterprise architecture for the middle tier with bold font in titles of MSDN. On the other hand you can find lots of strong restrictions for STA under COM+ written with smaller font in the very technical articles of the same MSDN. C’est la vie. But as a rule there is only a restriction mentioned and very rarely you can find a short explanation why it is not worth doing so. Keep in mind that some restrictions can be fatal for your architecture and you can never predict when and where it will happen. You should learn all the restrictions as well as investigate their real reasons and possible effects before picking out some particular architecture. So measure thrice and cut once before taking the final decision. And of course don’t buy bold titles of MSDN and other advertisement. You have to learn to read between the lines. And now I will help you to study a piece of Microsoft day-to-day advice Don’t make blocking calls from STA. Terse and clear.


First of all, there are two kinds of blocking calls. The first one is an implicitly blocking call. That happens when you are making an outgoing call to other components outside of the caller apartment or context and are synchronously waiting for the call to return back. Explicitly blocking call occurs when you are calling Sleep or WaitForSingleObject or something like that. If you are making a blocking call of any type, the message loop of the caller’s STA thread is blocked, which forces the activity's workflow to get blocked as well while it is waiting for the blocking call to return. During this time, the message loop cannot serve any other instances that live on that thread.The same is for components marked as Both. Don’t ever forget any Both component can be created from an STA component at any time and therefore it can also get into an STA apartment and thus it can also perform as a usual STA component.

COM+ STA pool has 7 + X threads and potentially can grow up to 10 * X, where X is a number of CPUs on the board. That is if we had 8 CPUs that pool would hold 15 threads initially and 80 threads at the maximum under stress. Suppose all the 15 threads are already busy handling incoming COM calls. After that COM+ starts to reuse these existing 15 threads. Such a technique is called multiplexing.

Michael McKeown, MS Engineer writes in MSDN as follows: Unlike MTS, COM+ binds up to five activities to a thread. That’s only a half of the truth. Actually COM+ operates in the following way. Let we have 1 CPU on the board. In that case COM+ distributes all incoming requests among 8 threads existing from the very beginning. After these existing 8 threads got 5 activities per thread (i.e. 40 activities) COM+ creates the ninth thread and bounds the next 5 activities to it. After that COM+ creates the tenth thread and bounds the next 5 activities to it. Now that COM+ has reached the upper limit of threads it begins to multiplex all incoming activities among 10 threads. That is COM+ binds up to five activities to a thread only when there are 8 initial threads. The upper limit is not five activities per thread. The upper limit is unknown actually. More precisely the upper limit is stack overflow but we won’t forestall.

Under MTS if all the threads are busy making out-of-apartment calls MTS queues incoming calls until some thread gets available to handle a call. But COM+ operates otherwise. Suppose an STA component receives an incoming call A, starts execution on the STA thread and makes out-of-apartment call. COM intermediate layer (so-called COM-channel) enters the thread’s modal message loop and feels ready to receive and handle another COM request to the same STA apartment while working RPC thread makes a real blocking call to the target component and actually waits for that blocking call to return. Another incoming call B to the same apartment can now be also served. Activity A is still waiting for return. Suppose activity B gets an incoming call B, starts execution and makes out-of-apartment call as well. Here lies the key point for understanding. Activity A won’t return control of the STA thread until Activity B completes handling of call B entirely. Imagine, all the components are of the same type and make out-of-apartment calls. That means A calls out, B calls out, C calls out and so on and so forth. So A waits for B to complete, B in its turn waits for C to complete etc. We’ve got a LIFO structure (Last In First Out). Execution time of A consists of its own execution time and B + C + etc execution time. This is the price we are forced to pay for the possibility to work around the blocking caused by out-of-apartment call from STA.

For those who make explicitly blocking call COM+ provides CoWaitForMutlipleHandles function. If the caller resides in an STA, CoWaitForMutlipleHandles enters the STA message modal loop, and the loop will continue to dispatch messages using the thread’s message filter. If no message filter is registered for the thread, the default COM message processing is used. If the calling thread resides in an MTA, CoWaitForMutlipleHandles just forwards the call to Win32 API function MsgWaitForMutlipleObjects.

And that is the double blessing. Can you see where the danger is coming up? Everything said above was just suspense.


Any serious contemporary n-tier architecture includes number of system services along with main business components. Before launching business logic it should log on to the system, get some context object which will be passed afterwards to all the underlying components ensuring exchange of system parameters and fulfilling other tasks like error collecting. Also it has to check permissions whether that particular user has the right to fulfill the requested task. It has to check if that particular user has bought the license necessary to fulfill the desired feature. As a rule it is system services, which are responsible for all this system functionality. Underlying business objects, as a rule, also make out-of-apartment calls, for example, to the united Locking Service. The services possess several advantages over other variants of implementation. The main advantage is that services can handle incoming requests when nobody is logged on to the system. Anyway, several calls are to be made out-of-process from any tier of n-tier architecture.

It would make sense to take out-of-proc callers out of COM+ but, you know, developers are fond of placing DLLs under COM+. They like that not only because COM+ ensures transactions, synchronization and other stuff. COM+ suggests approved dllhost.exe as a host for DLL to be available remotely. That’s also one of the main reasons where to place components to. So, accept the inevitable. You have got some COM+ components making out-of-apartment, out-of-context, out-of-process or even out-of-machine calls. There would seem to be nothing terrible about it. Even if you trusted titles of MSDN and created all the components in VB that is as STA components. Even in that case, there still would seem to be nothing awful. Slow performance under stress, that is all what it looks. Okay let’s conduct a simple but nice (as usual) test.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date