Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Simple Inter-process Communication system for .NET framework

0.00/5 (No votes)
12 Mar 2014 2  
This article introduces tiny library, that allows easily use IPC with C# (share objects, send messages and exchange data in few lines of code).

Introduction

This article introduces tiny library, that allows easily use IPC with C# (share objects, send messages and exchange data in few lines of code). Simple interface makes entry threshold very low even for beginners.

Background

On my first work place I've faced with such a term as Inter-Process Communication. There was high-level library, implemented with Delphi, which provided easy communication between several process via PID's, window handles, etc. Implementation of that library was quite difficult, and not plain for understanding (it used file mapping and windows messaging API). After I've switched to C#, I became interested whether there are any simple high-level API for IPC in C#.

Using the code

Basic solution is to use IpcChannel. In this way to share one object between 2 processes developer should write something like this code.

Server:

IpcChannel serverChannel = new IpcChannel("MyServerChannel");
ChannelServices.RegisterChannel(serverChannel);
RemotingConfiguration.RegisterWellKnownServiceType(
  typeof(IPCChannelRemoting.MyRemoteObject),
  "SharedObj", WellKnownObjectMode.SingleCall); serverChannel = new IpcChannel("MyServerChannel");IpcChannel 
ChannelServices.RegisterChannel(serverChannel); 
RemotingConfiguration.RegisterWellKnownServiceType(
  typeof(IPCChannelRemoting.MyRemoteObject),
  "SharedObj", WellKnownObjectMode.SingleCall);   

Client:

IpcChannel clientChanel = new IpcChannel("myClient");
ChannelServices.RegisterChannel(clientChanel); 
ISharedObj obj = (Remoteable.ISharedAssemblyInterface)Activator.GetObject(
  typeof(Remoteable.ISharedAssemblyInterface),
  "ipc://MyServerChannel/SharedObj "); 

But what if data exchange is used ubiquitously through application? In this case developer should duplicate such a code everywhere and stipulate rules to create URI for shared objects.

But what if developer need not just request data from another process, but subscribe for some signal/event from it? Of course, he can create some Thread/Timer to check it in cycle. Obviously he can't manage with it without some king of self-created architecture.

As I know from previous experience in developing application that uses IPC technology, it's very convenient to use and maintain following approach:

  • there are three entities: sender, receiver and message;
  • each receiver/sender has it's own unique ID, which is used for messages dispatching. For this goal developer can use, for example, application PIDs, window handles or any well-known identifier for each side of data exchange.
  • message - is abstract entity, that can contain property of any type. It can be synchronous or asynchronous. The difference between synchronous and asynchronous messages is that application, which receives message can put response in the same message (if it is necessary), and response will be accessible for dispatcher at once after message processing (on stack return). Applications, that send and receive such messages, should be aware of particular descendants of base message class.

    Eventually, with this system, data exchange between processes is reduced to the following steps:

  • create 'dispatcher' object and 'message' object;
  • dispatch message to desired receiver;
  • process message within receiver.

As you could notice, this approach is very similar to native Windows Api (postmessage/sendmessage/wndproc), but it supports OOP, events, easy passing real objects between processes, without deep knowledge of Inter process communication. Example:

using (BaseIPCDispatcher dispatcher = new BaseIPCDispatcher(slaveReceaverGUID)) {
  TestAsyncComplexMessage testMessage = new TestAsyncComplexMessage (ReceaverID, null);
  dispatcher.Dispatch(testMessage);
}

Subscription for this message in another (or the same) process:

…
Receiver.OnReceaveIPCMessage += OnReceaveMessage;
…
private void OnReceaveMessage(object sender, ReceaveMessageEventArgs e) {
  TestAsyncComplexMessage testAsyncMessage = e.Message as TestAsyncComplexMessage;
  if (testAsyncMessage != null) {
    // process message
  }
}

All code covered with functional tests using master/slave architecture. Here is the code. It as available also on https://github.com/perevernihata/SimpleIPCCommSystem .

Points of Interest

It made me sad, that such a powerful and high-level language as C# doesn't allow developer to share objects and exchange data between processes easily. At the same time it was a challenge for me to remake self-made Delphi IPC system in C#.

History

Version 1. (TODAY)

Version 2. Added direct link to the code sources.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here