2:
    A Object implementors decide the concurrency requirements of their objects by selecting which apartment types their objects can correctly execute in. Out-of-process servers explicitly decide their apartment type by calling CoInitializeEx with the appropriate parameter. This doesn't work for in-process servers, as the client will have already called CoInitializeEx by the time the new object is created. To allow in-process servers to control their apartment type, COM allows each CLSID to have its own distinct threading model that is advertised in the local registry using the ThreadingModel named value:   [HKCR\CLSID\{23156321-2312-11d0-2213-0080C73925BA}\InprocServer32]
 @="C:\rect.dll"
 ThreadingModel="Both"
      Each CLSID in a DLL can have its own ThreadingModel value. COM currently supports four in-process ThreadingModels. The absence of a ThreadingModel value implies that the class is completely thread-ignorant and can only run in the main single-threaded apartment (STA) in a process. The main STA is defined as the first STA to be created in the process via a call to CoInitializeEx using the COINIT_APARTMENTTHREADED flag. ThreadingModel=Apartment indicates that the class can execute in any STA in the process (not just the main STA), but cannot execute in the multithreaded apartment (MTA). ThreadingModel=Both indicates that the class can execute in either an MTA or any STA in the process. ThreadingModel=Free indicates that the class can execute only in an MTA and can never execute in an STA.
      To understand why ThreadingModel=Free exists, it is useful to look at what happens during an in-process activation request. Consider the following call to CoCreateInstance:  
 IPoint *pPoint = 0;
 CoCreateInstance(CLSID_Point, 0,
                  CLSCTX_INPROC_SERVER, 
                  IID_IPoint, (void**)&pPoint);
To make this call, the caller must first enter an apartment by calling CoInitializeEx, indicating which type of apartment to enter. If the caller's apartment is compatible with the CLSID_Point's threading model, then COM will instantiate the object directly in the apartment of the caller. This is by far the most efficient scenario, as no intermediate proxy is needed. If the client's apartment is incompatible with the CLSID_Point's threading model, then COM will silently instantiate the object in a distinct apartment and a proxy will be returned to the client. This means that method invocation performance will decrease by a factor of roughly 1000. 
      If the caller is executing in the MTA and CLSID_Point is ed ThreadingModel=Apartment, the class object (and subsequent instances) will execute in a new COM-created STA for the class. This ensures that the object (which is not prepared for concurrent access) will have all of its calls serialized automatically by COM. If CLSID_Point does not have a ThreadingModel value, then the class object (and subsequent instances) must execute in a main STA of the process. If the caller happens to be the main STA thread, then the object will be accessed directly. Otherwise, the client will get back a proxy. If no STAs exist in the process (that is, if no threads have called CoInitializeEx with the COINIT_APARTMENTTHREADED flag), then COM will create a new STA to act as the main STA for the process. An interesting case is where the caller is executing in an STA and CLSID_Point is ed ThreadingModel=Free. In this case, COM will activate the class object (and subsequent instances) in the MTA and return a proxy to the caller. This means that all of the object's methods will execute inside the MTA. 
      Implementors who  their classes as ThreadingModel=Apartment are stating that their instances must only be accessed from one thread for the lifetime of the object. This implies that there is no need to protect instance state (that is, per-object data members). However, any state that is shared by multiple instances of the class must be protected. Implementors who  their classes as either ThreadingModel=Free or ThreadingModel=Both are making the statement that instances of their class may run in the MTA, which means that a single instance of the class may be accessed concurrently. Because of this, implementors must protect all resources that are used by a single instance against concurrent access. This applies not only to shared static variables, but also to per-object data members. For heap-based objects, this implies that, at the very least, the reference count data member must be protected using InterlockedIncrement/InterlockedDecrement. Other class-specific instance states need to be protected as well. 
      At first glance, it is less than obvious why ThreadingModel=Free exists, since the requirements of running in an MTA are often seen as a superset of the requirements for STA-compatibility. One reason not to run in an STA is because all method invocations will happen on the client's thread. This means that the object's methods will not be serviced unless the client services its message pump regularly. Beyond this, ThreadingModel=Free is useful for objects that create or use additional worker threads as part of their normal operation. Assuming that the worker threads need access to the object, it is highly advantageous to keep the object from being created in an STA, especially if the object uses other COM objects to do its work. 
      Objects that run in an STA cannot be manipulated safely by other threads in the process. Because no worker threads can enter the apartment of an STA-based object, any worker-thread access will by definition be from a different apartment. If a class is ed ThreadingModel=Both or ThreadingModel=Apartment and an activation request is made from an STA-based thread, the object will live in an STA, causing this situation to occur.  
 
      Figure 1 ThreadingModel=Both with STA        As shown in Figure 1, this implies that the worker threads (which will probably run in the MTA or other STAs in the process) must access the object using inter-apartment method calls, which are considerably less efficient than intra-apartment method invocations. It is extremely tempting to cheat and simply pass a raw C++ pointer to the worker threads. This may work, provided the object does not use any other apartment-specific resources. But many objects use the services of other objects, and the interface pointers to these objects are definitely apartment-specific and cannot be accessed by worker threads that cheat and call into the object without a proxy. Attempts to do this are often rewarded with the infamous RPC_E_WRONG_THREAD error code, or better yet, with random program faults 20 seconds after the offending access.  
 
      Figure 2 ThreadingModel=Free with STA  
      If the object's class had been ed ThreadingModel=Free, then any activation requests would force the new instance to be created in the MTA, even if the caller is running in an STA. This means that any MTA-based worker threads can access the object directly and safely. However, as shown in Figure 2, an STA-based client will not get a pointer to the object, but instead will receive a pointer to a proxy. This means that when the STA-based client invokes methods on the object, the invocation cost will be considerably higher. However, the worker threads will experience much better performance without violating the rules of COM. Depending on the usage patterns of the object, this may or may not be a reasonable tradeoff. If the worker threads will manipulate the object frequently, then this is probably a good optimization. If the worker threads manipulate the object infrequently relative to the client's activity, then ThreadingModel=Free will actually hurt performance.