An out-of-process server is a component that is effectively a separate program containing objects. This type of server will always run in its own process space, and will thus be largely independent from any client programs.
There are two main options with out-of-process servers. We can create the server so that each object runs in its own process, or we can create the server so that all the objects in the server run within a single process.
There are cases where our business objects will be running in a number of separate processes. The most notable scenario is where we have a full-blown application that can also be used as a component. We might also create out-of-process servers when we want to start some task and let it run in the background while the user continues to work with our application.
There is a cost to this approach however. Most applications require many different business objects to be active all at the same time and, if each object runs in its own process, we'll have a lot of processes running concurrently. Having a great many processes active on a workstation can be devastating to performance.
The Windows operating system does some work every quantum (20 milliseconds or so) to determine which process should get to run next. Even if a process is idle, it is still in the list of processes to check, and so the operating system has to do some extra work to check our idle process. If we have a lot of processes, this can add up and become a problem:
On the other hand, we can create a server where all of our objects exist inside a single process. If we put business objects inside this type of server, all of the objects can work together, sharing resources and memory. Many clients can use the objects in our server, and all the objects from all those clients can easily communicate and work with each other inside the same process.
Either type of out-of-process server suffers from one very significant drawback: performance.
All Windows components use the Component Object Model (COM) to allow communication with objects in other processes. We'll discuss COM in more detail later in the chapter. For now, all we need to know is that COM handles all communication between objects in different processes.
Unfortunately, COM imposes a very high overhead on each call from one process to another (cross-process calls). Therefore, on each reference to a property and each call to a method, we take the hit of this overhead - and performance can suffer substantially.
There are techniques that can be used to help minimize the impact of this overhead, and I'll demonstrate those later in the book.