Designing Scalable Components for IIS
Because you should encapsulate most of your business logic within COM components, it is important that your components be designed for high performance, in addition to being readily scalable.
Here are some suggestions for creating scalable components:
Optimize your algorithms.
Make your component adhere to the proper threading. Page-scope components should be use either the Apartment or Both threading model; application-scope components should use the Both threading model, and should also aggregate the free-threaded marshaller. For more information about component threading issues, see the topic Selecting a Threading Model in the IIS SDK.
If your component uses the heap intensively, consider other heap alternatives. Intensive use of the Windows heap can cause resource contention. Several memory allocation alternatives are worth exploring, including:
Heap Partitioning, accomplished by creating multiple custom heaps, in addition to the default process heap. Each custom heap would then be controlled by a separate, non-global lock, and lock contention would be reduced.
Cached Allocation, which involves using custom allocation operations that operate at a middle layer between the object users and the heap. Calls to the Win32 heap are made infrequently, and only for large memory blocks. These blocks are then subdivided and managed by the custom allocator.
Stack Allocation, using the C run-time function _alloca to allocate memory for your objects on the stack instead of the heap. This method is feasible only for relatively small objects, because the space available on the stack is limited. In addition, your newly allocated object will be available only within the current functions, or functions called by that function. Once the current function returns, the storage allocated on the stack will be lost.
Object Encapsulation, accomplished by simply incorporating a buffer as a member data structure of your component class. This buffer is then used for tasks that would otherwise require accesses to the Win32 heap.
Avoid using global locks within your component, if possible. Global locks can often adversely affect component scalability.
If your component is running as part of an application, designate the application as out-of-process for application debugging only. Process isolation, introduced in IIS 4.0. is a useful capability. The cross-process marshalling required to support process isolation, however, can introduce a certain amount of overhead to component execution. This difference in overhead is most significant for simple components, and is less of a concern for more complex components. To maximize scalability and performance, however, consider running the application out-of-process only until it is sufficiently debugged and stable to be run in-process with IIS.
Consider placing your component in a library (in-process) COM+ application. As part of the Just-In-Time activation feature of Component Services, the component's COM class factory is cached, and reused for each instantiation request through CreateInstance.