.Net Remoting (AppDomains, Out of Process, Two Way, etc..)

I previously wrote about bi-directional remoting over IPC (see  .Net Remoting continued and .Net Remoting).  Several people asked for complete sample code.  Ok, the squeaky wheel gets the attention.  This could be an indication of my poor writing skills 😉 or the difficulty in figuring out remoting, or a little of both. 

I also want to let you know that if you are a Host or ISV providing extensibility (in or out of process), I highly recommend utilizing the BCL’s Add-In model instead of rolling your own.  Particularly, in lieu of using the sample app I am attaching.  I left a lot of out!!!  The code is more likely appropriate as an understanding of some principles or as an internal implementation (i.e., Not for 3rd party extensibility).  In the current Orcas CTP (I’ll post more on this) we have added out of process support to the System.AddIn BCL!!!

Two Way Communications

First, I want to let you know that in putting together this sample application I discovered I was wrong (don’t tell anyone) about the need to create another channel for handling incoming calls in addition to outgoing calls.  Both IPC and TCP work with a single channel.  Most of the issues had to do with that pesky typefilter.  I guess none of the Indigo team members read my blog because no one corrected me.   Hey, wait a minute.  If no one noticed I was wrong and I corrected my mistake, I was only mistaken, not *wrong*.

I will show sample code of a remote object method invocation from a Host to a Remote app and vice versa.  You may think in terms of a client and server if you wish, but I created so many samples that it became very confusing when an app worked like a client and a server, so I chose HostApp and RemoteApp as terms. 

I also want the reader to know that a two way remoting method, whereby a Host instantiating an object, utilized for a remote process to call into and (i.e., not OR) vice versa is not a typical scenerio.  

In a Host to Add-In model and in many other mainstream scenarios, the need to enable two-way method invocation in *both* the Server and Client is rare. 

The typical way a “two-way” communication takes place is when one side (Client or Server) instantiates the others object and then uses that object to pass Serializable or MarshalByRef objects to the methods of the instantiated object.  Or you instantiate a local, remotable object, that is called into from the remote application but rarely combinations of the two.  In other words, the typical method employed is to instantiate (e.g., new) your object locally and as long as the object can be Marshaled, it is just passed to the remote client or server over an existing remoting channel via an objects method that takes the remotable object as a parameter.  It may be hard to tell but I did try to make all that clear L  I think the samples and the comments may make it clearer.

Sample code

·         I have included an example of an IPC and TCP remoting channel.

·         I used the Binary formatter since it is the most efficient.

·         Notice the typefilter settings I blogged about.

·         Remote method invocation may be accomplished in several ways

o   via RemotingServices.Marshal // which is what I did in the sample

o   via a config file and RemotingConfiguration.Configure(@”C:\blah \Client.exe.config”, false); // I have prototyped this method successfully

o   via RemotingConfiguration.RegisterWellKnownServiceType // I had issues with this method.  Read as – Good luck with that.

·         AppDomains

  • Remoting channels are only needed for Cross Process remote AppDomain communications.  In process, cross AppDomain calls do not require a remoting channel.

  • You may not wish to run code in a remote processes default AppDomain.  So I added a more complex example of a remote process, non-default AppDomain, since this is another tricky bit to work out when doing remoting.  When running a “server/Host” In-process you don’t a channel per AppDomain, just a primary channel to handle incoming and outgoing calls.  But for AppDomains in a remote process you need a channel per AppDomain for the calls.

The Source code may be found here.

Comments (12)

  1. Benny Tordrup says:

    The scenario looks interesting. But what if the remote app is a currently running application? How would you make the remote app find out about a new client?

    And further: Could this be made work cross machine and not just cross appdomain?

  2. JackG says:

    The sample starts a process but an existing process would work just as well if the remote app process (and AD’s within) establish a channel.  As far as discovery is concerned, it is usualy the Host app that discovers Add-Ins  or clients that discover a server.

    Cross machine is supported via the TCP sample I gave. Although I used localhost it could just as well be a remote machine name.  IPC only runs on the same machine.  -JackG

  3. Jeff Crain says:

    Since it appears you can have only one registered ICP or TCP channel, how would you remote an object such that multiple objects can be created in unique processes (like an out of process, single-use server)? I have a supplier’s api that I wrapped in an activex exe. The api can connect to a single database at a time, and is not multi-threaded. So creating an out-of-process server for each instance works fine. But I’m not sure how to do this with remoting. Just wondered if you had any ideas?

  4. JackG says:

    Hi Jeff, Channels do not have a 1:1 correspondence to remoted objects.  Once a channel is established, you may marshal as many objects as you like on the same channel.

  5. tomBig says:

    Hi Jack

    interesting information that youre providing. Just one question: Does your statement

    “Remoting channels are only needed for Cross Process remote AppDomain communications.  In process, cross AppDomain calls do not require a remoting channel.”

    mean that I can use remoting without having ANY channels registered in the ChannelServices at all ?



  6. JackG says:

    Hi Tom, Correct. For example, If your object derives from MarshalByRef and you cross an AppDomain boundary, within a process, you will be using CLR remoting but you do not have to setup a channel. – JackG

  7. In this post I will be showing sample code (also found on our CodePlex site ) as well as an execution

  8. Sergey says:


    In your sample code, HostApp/program.cs, line 98, you write ‘let the external process spin up or you get:  system cannot find the file specified.’ Could you please explain why this happens? I’ve come across exactly the same behaviour in one of my own apps and had to use Thread.Sleep as a temporary work around. Is there a more deterministic way of detecting when the out-of-process server is ready?



  9. JackG says:

    Sergey, That is a great (frequently asked)  question. I think the answer deserves some sample code as the API and doc’s leave much to the imagination. I will post a blog entry ASAP on the subject. JackG

  10. function ToggleDisplay (label, control) { if (control.style.display == "none") { control.style.display

  11. JackG says:

    Sergey, I have published a sample on xternal process creation and coordination (http://blogs.msdn.com/jackg/archive/2008/08/11/process-creation-and-coordination.aspx).