2个C#进程之间最简单的进程间通信方法是什么?


70

我想在父进程和子进程之间创建通信,两者均使用C#编写。

它应该是异步的,事件驱动的。

我不想在每个进程中运行一个线程来处理非常罕见的通信。

最好的解决方案是什么?


2
我已经在我的博客上写了一篇关于使用WCF中的命名管道进行进程间通信的非常简单示例的文章。https://dopeydev.com/wcf-interprocess-communication/
Riain McAtamney '16年

您是在谈论异步过程还是异步通信?第一个可以使用WCF或WebServices或通过tcp或管道进行的任何操作来完成。但是异步通信需要诸如MSMQ或Azure Service Bus或RabbitMQ之类的排队技术。
丹尼斯·范·德·斯特尔特

Answers:



21

如果您的进程在同一台计算机上,则只需使用stdio即可

这是我的用法,一个网页屏幕截图:

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();
}

在Main上检测args

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);
        }
    }
    //...
}

5
但是,如果目标进程需要具有GUI(即ProcessStartInfo.UseShellExecuteis),则将无法工作true。在这种情况下,您将无法重定向标准输出和错误。
Guido Domenici

@JayCroghan我认为当它具有GUI时,您不可以使用它。至少在从Web应用程序启动客户端进程时。
巴兰尼卡斯先生17年

8

我建议使用Windows Communication Foundation:

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

您可以来回传递对象,使用各种不同的协议。我建议使用二进制tcp协议。


86
...那么复杂的方法是什么?
dfasdljkhfaskldjhfasklhf,2009年

74
如果WCF是“最简单的方法”,我真的想哭:P
kizzx2

2
@ kizzx2我们将以很大的方式开始使用WCF,一旦经历了最初的困惑,WCF真的很棒。我发现这个人的简单实现非常有用devx.com/codemag/Article/39837
查理A

3
@CharlieAspinall,如果5页C#和XML很简单。我真的很想哭。
Daniel Santos

WCF是REST的Web服务包装器。该问题与Windows进程有关。
bytecode77


3

还有COM

有技术,但是我想说的好处是您将能够调用可以定义的方法。

MSDN提供了C#COM互操作教程。请搜索,因为这些链接确实发生了变化。

要立即开始,请在这里...



1

当不考虑安全性且受您的限制(同一台计算机上有两个C#进程)时,C#中用于进程间通信的最简单解决方案是Remoting API。现在,Remoting是一项遗留技术(与已弃用的技术不同),不鼓励在新项目中使用,但它确实能很好地工作,并且不需要很多浮躁和环境来工作。

在MSDN上IpcChannel有一篇很棒的文章,它使用Remoting框架中的类在这里可以找到Greg Beech的信用)来建立简单的远程服务器和客户端。

我建议先尝试这种方法,然后再尝试将代码移植到WCF(Windows Communication Framework)。具有多个优点(更好的安全性,跨平台),但必定更复杂。幸运的是,MSDN上有一篇很好的文章,将代码从Remoting移植到WCF

如果您想立即使用WCF进行学习,这里有一个很棒的教程


-1

死灵法师

如果可能的话,创建共享文件更容易!

//out
File.AppendAllText("sharedFile.txt", "payload text here");
// in
File.ReadAllText("sharedFile.txt");
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.