I was interested by this article at O'Reilly - Previewing Windows .NET Servers, in particular the enhanced process model in IIS 6.0. I've advocated for a long time that complex server applications should be partitioned into separate processes, wherever feasible, to isolate different components of the server into their own address space. When using an unsafe language like C++ this tends to make the overall application more robust and makes it more obvious which components have faulty code. I worked on one very complex single-process application in which memory corruption bugs were still being discovered several years after the code had been written and in which inexplicable problems occurred at random intervals. With several hundred thousand lines of heavily multi-threaded code it was impossible to pinpoint the problems. Of course there is an overhead in making cross-process calls but if the server is partitioned sensibly these should not be an unacceptable overhead.
In IIS 6.0 inetinfo.exe is now a separate process with no apps running in its address space. This process controls multiple worker processes, each process running one or more apps. There is also the new concept of a "web garden" where a group of processes is configured to run an application pool. This is useful because, in addition to allowing better scalability, say a problem in a app only occurs in a rarely followed code path: in the web garden approach, if the problem occurs it will only bring down one of the processes in the web garden, leaving the other processes to continue handling the normal cases. IIS also allows processes to be recycled after handling a specififed number of requests so that the effects of leaky apps can be minimised. It also enables processes to be configured to be restarted automatically should a crash occur.
.NET App Domains are a method of partitioning .NET applications. An App Domain is the .NET equivalent of an OS process. More than one App Domain can be configured in a single OS process, with the state of each App Domain completely isolated from the other App Domains in the same process. If an unhandled exception occurs in one App Domain it only causes that App Domain to be shut down, the others being unaffected. However this assumes that the code running in the App Domains is verifiably safe. Any unsafe code and all bets are off because there is potential for memory corruption across the App Domains. In this case the only robust approach is to isolate the unsafe code in a separate OS process.
There is still an overhead when making cross-domain calls but I don't know how this compares to the cross-process case. If it is anything like the difference between cross-process COM calls and cross-apartment calls in the same process it will be an order of magnitude or so faster. I'll have to do some research or experimentation on this.