Click here to Skip to main content
13,861,429 members
Click here to Skip to main content
Add your own
alternative version


167 bookmarked
Posted 4 Apr 2002
Licenced CPOL

Absolute beginner's introduction to remoting

, 4 Apr 2002
Rate this:
Please Sign up or sign in to vote.
Introduces .NET remoting and the use of asynchronous callbacks using simple code snippets


Remoting allows you to work with objects remotely. It is a lot more efficient than SOAP based web services but obviously it can only be used within intranets. On the internet you would have problems with firewalls, and an overall lack of security.

In really simple terms you have a client program running on a machine invoking functions on an object that is instantiated on a different machine. Let's jump into some really short and crisp code snippets. Usually I find that it's easier to understand a concept by looking at a small code snippet than if you read a 2000 word essay giving you all kinds of complicated theory. Of course any extra theory you learn is always going to help in a lot of ways.

The interface

The first thing we do is to create an interface called MyInterface. Then we'll compile it into a dll. Later we'll derive our remote class from this interface. Now, what this does for us is that on the client machine we can use this interface. Otherwise we'd have had to use the class directly from the client machine which pretty much makes the whole exercise a little futile.

// csc /t:library MyInterface.cs

public interface MyInterface
    int FunctionOne(string str);

The object

Now that we have our interface ready, let's create our class which we will invoke from a remote machine. We derive this class from MarshalByRefObject and MyInterface. Any class derived from MarshalByRefObject allows remote clients to invoke it's methods, which is just what we are trying to do here.

// csc /t:library /r:MyInterface.dll RemoteObject.cs

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;

public class MyRemoteClass : MarshalByRefObject,MyInterface
    public int FunctionOne(string str)
        return str.Length;

The server

Now, let's write our remote server.

// csc /r:RemoteObject.dll RemoteServer.cs
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

public class MyServer
    public static void Main()
        TcpChannel m_TcpChan = new TcpChannel(9999);
        System.Console.WriteLine("Press ENTER to quit");

First we create a TcpChannel object which we use to transport messages across our remoting boundary. As you can see, I have also selected 9999 as the TCP port to listen on. Now you can understand how this would cause a hell of a lot of problems with firewalls. We use ChannelServices.RegisterChannel to register our TcpChannel with the channel services. Don't ask me what exactly goes inside that function. All I could figure out is that if you don't register the channel, remoting won't work. Now we use RemotingConfiguration.RegisterWellKnownServiceType to register our MyRemoteClass object as a well-known type. Now this object can be remoted.

The first time I saw the huge function name, I thought it was some kind of joke. But then the .NET framework has thousands of functions and classes and thus I guess they didn't really have a choice. It's a lot better than calling it __rwkst(...), I guess. I am using the word FirstRemote here which will be used as part of the URL that the client uses to access the remote object. I specified the SingleCall mode here, which means a new instance is created for each remote call. I could have used Singleton in which case one object would have been instantiated and used by all connecting clients. I guess if this was an advanced article [which it is not] written by an advanced level programmer [which I am not], there would have been some explanation as to the differences between the two modes.

The client

Okay, now run your server on one of the machines. Now let's take a look at the client which can be run on the same or on a separate machine. I had to run it on the same machine for some complicated technical reasons. Well to be honest, the complicated technical reason was that I had only one machine at home.

// csc /r:MyInterface.dll client.cs

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

class MyClient
    public static void Main()
        TcpChannel m_TcpChan = new TcpChannel();
        MyInterface m_RemoteObject = (MyInterface)

Just as in the server, we have a TcpChannel object, though in this case we don't specify a port. We also use ChannelServices.RegisterChannel to register the channel. We use Activator.GetObject to get an instance of the MyInterface object. As you can see I have used the hostname 'earth' in my URL, as that's my machine's hostname. In your case you'd have to replace it with the name of the remote machine or it's IP address. The word 'FirstRemote' which forms part of the URL was what I had passed to RemotingConfiguration.RegisterWellKnownServiceType on the server. Now that I have got my object I can call its member functions. Well, that was not too difficult now, was it?

Asynchronous Callbacks

In our client we have used synchronous calls to the remote object. The problem with this, is that if the function takes quite a while to execute, our program hangs until the function returns. Of course you could start a worker thread each time you wanted to access a remote method, but isn't very efficient. And if by any chance you are passing shared data to the method and also getting some shared data back, you would have to take care of thread synchronization. The good news is that you don't have to do all that complicated stuff. You can use asynchronous callbacks.

// csc asyncclient.cs /r:MyInterface.dll

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Messaging;

class MyClient
    public delegate int MyDelegate(string s);
    public static void Main()
        TcpChannel m_TcpChan = new TcpChannel();
        MyInterface m_RemoteObject = (MyInterface)
        MyDelegate m_delegate = 
            new MyDelegate(m_RemoteObject.FunctionOne);
            new AsyncCallback(MyCallBack),null);
        System.Console.WriteLine("Press ENTER to quit");

    public static void MyCallBack(IAsyncResult ar)
        int l = ((MyDelegate)((AsyncResult)ar).AsyncDelegate).EndInvoke(ar);

Here we have two delegates. Delegates are type safe function pointers. The first delegate is one we create called MyDelegate. We point this to the function we need to access from our remote object. Now we call the function BeginInvoke. The first parameter is the parameter we pass to the actual function. The second parameter is another delegate of the AsyncCallback delegate type. What happens now is that the remote function is called but control returns immediately and our program won't block. Later, when the remote object completes the execution of the function, our callback is called with an IAsyncResult parameter which encapsulates the results of an asynchronous operation on an asynchronous delegate. We use the AsyncDelegate property to get our delegate and cast it to MyDelegate and call EndInvoke on it to get the results of the remotely executed function. You must keep in mind that the remote function has already terminated and its termination has nothing to do with EndInvoke. EndInvoke simply gives us back the results of the operation.


I really do hope that the beginners who read this article have found this article useful. There is a lot more to remoting and if I do learn more stuff, I'll post more articles on it here.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Nish Nishant
United States United States
Nish Nishant is a Principal Software Architect based out of Columbus, Ohio. He has over 17 years of software industry experience in various roles including Lead Software Architect, Principal Software Engineer, and Product Manager. Nish was a Microsoft Visual C++ MVP between 2002 and 2015.

Nish is an industry acknowledged expert in the Microsoft technology stack. He authored C++/CLI in Action for Manning Publications in 2005, and had previously co-authored Extending MFC Applications with the .NET Framework for Addison Wesley in 2003. In addition, he has over 140 published technology articles on and another 250+ blog articles on his WordPress blog. Nish is vastly experienced in team management, mentoring teams, and directing all stages of software development.

Contact Nish : If you are interested in hiring Nish as a consultant, you can reach him via his google email id voidnish.

Company Website :

You may also be interested in...

Comments and Discussions

GeneralRe: Runtime error - null value Pin
simon.walding6-Jan-04 6:16
membersimon.walding6-Jan-04 6:16 
GeneralRe: Runtime error Pin
calvinchoi16-Aug-06 1:17
membercalvinchoi16-Aug-06 1:17 
GeneralCan Pin
Anonymous6-Jul-03 7:18
memberAnonymous6-Jul-03 7:18 
GeneralRe: Can Pin
Nish Nishant23-Jul-03 7:53
sitebuilderNish Nishant23-Jul-03 7:53 
QuestionReference required? Pin
Anonymous10-Jun-03 16:26
memberAnonymous10-Jun-03 16:26 
AnswerRe: Reference required? Pin
Nish Nishant23-Jul-03 7:54
sitebuilderNish Nishant23-Jul-03 7:54 
GeneralRe: Reference required? Pin
Opa Knack5-Dec-04 3:50
memberOpa Knack5-Dec-04 3:50 
GeneralEvents Pin
CSharpDavid27-May-03 18:28
memberCSharpDavid27-May-03 18:28 
Nish, thanks again for clearing the muddy microsoft waters. I was wondering if it would be possible to use events on the server to call stuff on the client. I cannot work out how to declare an event in the interface,

public delegate void UserRequest(object sender, EventArgs e);
Interfaces cannot declare types.
GeneralThe Best Pin
KaCaloy27-Mar-03 19:56
memberKaCaloy27-Mar-03 19:56 
GeneralRe: The Best Pin
Nish Nishant27-Mar-03 20:57
sitebuilderNish Nishant27-Mar-03 20:57 
GeneralSpeed Pin
CSharpDavid27-Mar-03 9:10
memberCSharpDavid27-Mar-03 9:10 
GeneralRe: Speed Pin
Nish Nishant27-Mar-03 20:01
sitebuilderNish Nishant27-Mar-03 20:01 
GeneralRe: Speed Pin
Nish Nishant27-Mar-03 20:54
sitebuilderNish Nishant27-Mar-03 20:54 
GeneralRe: Speed Pin
Adam Turner16-Apr-03 19:08
memberAdam Turner16-Apr-03 19:08 
GeneralRe: Speed Pin
Nish Nishant16-Apr-03 19:59
sitebuilderNish Nishant16-Apr-03 19:59 
GeneralExcellent article Pin
C_Wizard6-Feb-03 13:46
memberC_Wizard6-Feb-03 13:46 
GeneralRe: Excellent article Pin
Nish Nishant27-Mar-03 20:50
sitebuilderNish Nishant27-Mar-03 20:50 
Generalwowwww !!! Pin
Gethsus</s2-Dec-02 8:13
memberGethsus</s2-Dec-02 8:13 
GeneralRe: wowwww !!! Pin
Nish Nishant2-Feb-03 14:42
sitebuilderNish Nishant2-Feb-03 14:42 
GeneralExtremly usefull Pin
Mauricio Ritter6-Jun-02 13:11
memberMauricio Ritter6-Jun-02 13:11 
GeneralRe: Extremly usefull Pin
Nish Nishant6-Jun-02 15:09
sitebuilderNish Nishant6-Jun-02 15:09 
GeneralExtremely helpful Pin
3-May-02 4:46
suss3-May-02 4:46 
GeneralRe: Extremely helpful Pin
Nish Nishant3-May-02 5:42
sitebuilderNish Nishant3-May-02 5:42 
GeneralVery nice work, Nish Pin
Tom Archer21-Apr-02 17:54
memberTom Archer21-Apr-02 17:54 
GeneralRe: Very nice work, Nish Pin
Nish Nishant22-Apr-02 1:05
sitebuilderNish Nishant22-Apr-02 1:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web05 | 2.8.190214.1 | Last Updated 5 Apr 2002
Article Copyright 2002 by Nish Nishant
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid