Click here to Skip to main content
Click here to Skip to main content
Go to top

Simple Inter-process Communication system for .NET framework

, 12 Mar 2014
Rate this:
Please Sign up or sign in to vote.
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

rikkiua
Software Developer Unwind Technology
Ukraine Ukraine
No Biography provided
Follow on   LinkedIn

Comments and Discussions

 
QuestionLooks great.. but, where is the code? Pinmemberaquila_prosperus13-Mar-14 1:01 
AnswerRe: Looks great.. but, where is the code? Pinmemberrikkiua13-Mar-14 1:08 
QuestionNice! PinprofessionalVolynsky Alex12-Mar-14 2:26 

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

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

| Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 12 Mar 2014
Article Copyright 2014 by rikkiua
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid