【问题标题】:What is the simplest method of inter-process communication between 2 C# processes?2个C#进程之间最简单的进程间通信方法是什么?
【发布时间】:2010-10-06 10:22:13
【问题描述】:

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

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

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

什么是最好的解决方案?

【问题讨论】:

标签: c# ipc


【解决方案1】:

Anonymous pipes.

对 BeginRead/BeginWrite 和 AsyncCallback 使用异步操作。

【讨论】:

    【解决方案2】:

    如果您的进程在同一台计算机上,您可以简单地使用 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);
            }
        }
        //...
    }
    

    【讨论】:

    • 如果目标进程需要有一个 GUI,即如果 ProcessStartInfo.UseShellExecutetrue,则不会工作。在这种情况下,您无法重定向标准输出和错误。
    • @JayCroghan 我认为当它有 GUI 时你不能使用它。至少在从 Web 应用程序启动客户端进程时。
    【解决方案3】:

    我建议使用 Windows Communication Foundation:

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

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

    【讨论】:

    • ...那么复杂的方法是什么?
    • 如果WCF是“最简单的方法”,我真的很想哭:P
    • @kizzx2 我们开始深入了解 WCF,一旦你经历了最初的困惑,WCF 真的很酷。我发现这家伙的简单实现真的很有用devx.com/codemag/Article/39837
    • @CharlieAspinall 如果 5 页 C# 和 XML 很简单。我真的很想哭。
    • WCF 是 REST 的 Web 服务包装器。这个问题与 Windows 进程有关。
    【解决方案4】:

    【讨论】:

      【解决方案5】:

      还有COM

      有一些技术细节,但我想说优点是你可以调用你可以定义的方法。

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

      要立即开始,请转到here...

      【讨论】:

        【解决方案6】:

        还有 MSMQ(Microsoft 消息队列),它可以跨网络运行,也可以在本地计算机上运行。虽然有更好的沟通方式,但值得研究:https://msdn.microsoft.com/en-us/library/ms711472(v=vs.85).aspx

        【讨论】:

          【解决方案7】:

          在 C# 中最简单的解决方案是 Remoting API,用于在不考虑安全性并考虑到您的限制(同一台机器上的两个 C# 进程)的情况下进行进程间通信。现在 Remoting 是一项遗留技术(与已弃用的技术不同),不鼓励在新项目中使用,但它确实运行良好,并且不需要大量的盛况和环境即可开始工作。

          Remoting 框架中有一个excellent article on MSDN for using the class IpcChannel(归功于Greg Beech for the find here),用于设置简单的远程服务器和客户端。

          我建议先尝试这种方法,然后尝试将您的代码移植到 WCF(Windows 通信框架)。它有几个优点(更好的安全性、跨平台),但必然更复杂。幸运的是 MSDN 有一个very good article for porting code from Remoting to WCF

          如果您想立即通过WCF there is a great tutorial here 开始。

          【讨论】:

            【解决方案8】:
            【解决方案9】:

            死灵法

            如果可能的话,制作共享文件会更容易!

            //out
            File.AppendAllText("sharedFile.txt", "payload text here");
            // in
            File.ReadAllText("sharedFile.txt");
            

            【讨论】:

              猜你喜欢
              • 2018-05-31
              • 2014-07-12
              • 2010-12-20
              • 2019-04-20
              • 2018-05-31
              • 1970-01-01
              • 1970-01-01
              • 2011-06-24
              相关资源
              最近更新 更多