To enhance the scalability of your applications, Visual FoxPro provides SingleUse Objects and Apartment-model threading as ways of controlling issues of call blocking.
You can cause each instance of an OLEPUBLIC class to run in a separate instance of your component by setting the Instancing property of the OLEPUBLIC class to SingleUse in the Project Info dialog box. This means that even though your component is single-threaded, each instance of the SingleUse class has its own thread of execution. The behavior of SingleUse objects differs between .exe and .dll servers.
SingleUse Objects in EXE Servers
With the Instancing property set to SingleUse, each instance causes a new EXE process to begin. On Windows 2000 or later, you will see each running process in the Task Manager. With the MultiUse setting, the first instance will cause a new process to start, but each new object instance shares the same process as the first.
SingleUse Objects in DLL Servers
The Instancing property is ignored for multithreaded .dlls and is only read for the VFP9R.dll run-time library. Servers built for use with the VFPVersionNumberT.dll run-time library, with VersionNumber representing the version number for this release, are always MultiUse regardless of their setting. In general, you should always set the Instancing property to MultiUse for VFPVersionNumberR.dll in-process servers. If you set it to SingleUse, only one instance of an object from that server can be created. You will get an error if you try to instantiate more objects.
Only under rare circumstances would you want to use the SingleUse setting. In fact, Microsoft Transaction Server components require the MultiUse setting. SingleUse objects often require more memory overhead than multiple objects in a multithreaded component. There are reasons, however, for which you might want to use SingleUse objects. For example, you can isolate high-risk activities in separate processes with SingleUse objects. If the object suffers a fatal error, other processes are not affected. By contrast, a fatal error in a multithreaded component terminates all threads.
Visual FoxPro Automation servers now support Apartment-model threading. The Microsoft Transaction Server utilizes servers marked as apartment-threaded and offers better thread protection and scalability through serialization and marshaling.
In Visual FoxPro, apartment-model threading provides thread safety. In apartment-model threading, each thread is like an apartment вЂ” all objects created on the thread live in this apartment, and are unaware of objects in other apartments. Each Apartment-model object (such as a Visual FoxPro Automation server) may only be entered by one thread, the thread that created the object. However, an object server (such as Microsoft Transaction Server) can support multiple objects, each being entered simultaneously by different threads. Common data held by the object server must be protected against thread collisions.
Apartment-model threading provides the following benefits:
All of the objects a client creates on a given thread are created in the same apartment (thread) in the DLL. Calls on the same thread to these objects do not require cross-thread marshaling, making them more efficient.
Because an object is only accessed on the thread on which it was created, calls are serialized so that a call is never interrupted by a call from another thread.
Arguments for cross-thread calls are marshaled, and the calling thread is blocked. This synchronization of data protects the calling thread's state.
Apartment-threaded DLLs cannot create their own threads; the first time a client thread requests an object provided by your DLL, a new apartment is created, and the object Init event runs for that apartment. All single threaded client objects requested by that client will reside in the same apartment, and will share global data. Any PRIVATE objects (including forms) that are created by the public objects will also reside in the apartment.
Though Visual FoxPro does not provide a way for apartments to access each other, a multithreaded client could obtain a reference to an object on Thread A, and pass that reference to an object on Thread B.
For more information about Apartment-model threading, search on "Apartment-Model Threading" in the MSDN library.
The Visual FoxPro implementation of Apartment-model threading eliminates conflicts in accessing global data from multiple threads by giving each apartment its own copy of global data. This means that all objects created on the thread exist in this apartment, and are unaware of objects in other apartments.
Visual FoxPro uses thread local storage to store a unique set of application and environment global data for each thread (apartment). This means that two instances of the same class created on different threads cannot access each other's data. However, if these same two instances reside on the same thread, each object can access the other's data. This could cause timing issues for your applications. In fact, as long as two objects on the same thread are created from OLEPUBLIC classes in the same .dll server, data from those objects is common between them (Note: You can use the Session class to give each object a unique private datasession.)
In addition to thread local storage, Visual FoxPro also provides each project (.dll) a unique set of globals data. Objects created from different projects (.dll servers) cannot access each other's globals, even if the two objects reside on the same thread.