91

I want to create a communication between a parent and a child process, both written in C#.

It should be asynchronous, event-driven.

I don't want to run a thread in every process to handle the very rare communication.

What is the best solution for it?

4

9 Answers 9

56

Anonymous pipes.

Use Asynchronous operations with BeginRead/BeginWrite and AsyncCallback.

23

If your processes in same computer, you can simply use stdio.

This is my usage, a web page screenshooter:

var jobProcess = new Process();

jobProcess.StartInfo.FileName = Assembly.GetExecutingAssembly().Location;
jobProcess.StartInfo.Arguments = "job";

jobProcess.StartInfo.CreateNoWindow = false;
jobProcess.StartInfo.UseShellExecute = false;

jobProcess.StartInfo.RedirectStandardInput = true;
jobProcess.StartInfo.RedirectStandardOutput = true;
jobProcess.StartInfo.RedirectStandardError = true;

// Just Console.WriteLine it.
jobProcess.ErrorDataReceived += jp_ErrorDataReceived;

jobProcess.Start();

jobProcess.BeginErrorReadLine();

try
{
    jobProcess.StandardInput.WriteLine(url);
    var buf = new byte[int.Parse(jobProcess.StandardOutput.ReadLine())];
    jobProcess.StandardOutput.BaseStream.Read(buf, 0, buf.Length);
    return Deserz<Bitmap>(buf);
}
finally
{
    if (jobProcess.HasExited == false)
        jobProcess.Kill();
}

Detect args on Main

static void Main(string[] args)
{
    if (args.Length == 1 && args[0]=="job")
    {
        //because stdout has been used by send back, our logs should put to stderr
        Log.SetLogOutput(Console.Error); 

        try
        {
            var url = Console.ReadLine();
            var bmp = new WebPageShooterCr().Shoot(url);
            var buf = Serz(bmp);
            Console.WriteLine(buf.Length);
            System.Threading.Thread.Sleep(100);
            using (var o = Console.OpenStandardOutput())
                o.Write(buf, 0, buf.Length);
        }
        catch (Exception ex)
        {
            Log.E("Err:" + ex.Message);
        }
    }
    //...
}
2
  • 6
    Won't work however if the target process needs to have a GUI, i.e. if ProcessStartInfo.UseShellExecute is true. In that case you cannot redirect standard output and error. Aug 27, 2015 at 12:29
  • @JayCroghan i don't think you can use it when it has a GUI. At least when the client process is launched from a web application. Aug 2, 2017 at 6:08
9

I would suggest using the Windows Communication Foundation:

http://en.wikipedia.org/wiki/Windows_Communication_Foundation

You can pass objects back and forth, use a variety of different protocols. I would suggest using the binary tcp protocol.

5
  • 102
    ... so what's the complicated way then? Feb 9, 2009 at 15:50
  • 90
    If WCF is the "simplest method", I really want to cry :P
    – kizzx2
    Aug 30, 2010 at 5:57
  • 2
    @kizzx2 We're starting to get into WCF in quite a big way and once you've gone through the initial confusion WCF is really cool. I found this guy's simple implementation really useful devx.com/codemag/Article/39837
    – Charlie A
    May 15, 2013 at 14:16
  • 6
    @CharlieAspinall if 5 pages of C# and XML is simple. I really really want to cry. Sep 19, 2016 at 19:17
  • WCF is a web service wrapper for REST. The question relates to Windows processes.
    – bytecode77
    Jun 13, 2017 at 12:42
7

Named pipes on WCF.

http://msdn.microsoft.com/en-us/library/ms733769.aspx

3

The easiest solution in C# for inter-process communication when security is not a concern and given your constraints (two C# processes on the same machine) is the Remoting API. Now Remoting is a legacy technology (not the same as deprecated) and not encouraged for use in new projects, but it does work well and does not require a lot of pomp and circumstance to get working.

There is an excellent article on MSDN for using the class IpcChannel from the Remoting framework (credit to Greg Beech for the find here) for setting up a simple remoting server and client.

I Would suggest trying this approach first, and then try to port your code to WCF (Windows Communication Framework). Which has several advantages (better security, cross-platform), but is necessarily more complex. Luckily MSDN has a very good article for porting code from Remoting to WCF.

If you want to dive in right away with WCF there is a great tutorial here.

3

There's also COM.

There are technicalities, but I'd say the advantage is that you'll be able to call methods that you can define.

MSDN offers C# COM interop tutorials. Please search because these links do change.

To get started rightaway go here...

3

If possible, it's just easier to make a shared file!

//out
File.AppendAllText("sharedFile.txt", "payload text here");
// in
File.ReadAllText("sharedFile.txt");
3
  • 6
    Or you could bang two rocks together... this method would require polling and extra error handling around locked files etc. and is NOT event driven. Sure, it could work, but...
    – LordWabbit
    Apr 20, 2022 at 9:28
  • I think this is not such a bad answer. .NET supplies a very neat class to make this event driven: stackoverflow.com/a/721743 Sep 5, 2022 at 11:35
  • @LordWabbit It could work, and it does. The question is not about the "best" method, but the "simplest". This is one of the simplest methods imaginable. And this answer may not be the best, but surely is far more useful than your rocks-banging analogy, or, in fact, your whole condescending comment.
    – Daniel
    Mar 30, 2023 at 10:43
2

There's also MSMQ (Microsoft Message Queueing) which can operate across networks as well as on a local computer. Although there are better ways to communicate it's worth looking into: https://msdn.microsoft.com/en-us/library/ms711472(v=vs.85).aspx

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.