80

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

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

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

什么是最好的解决方案?

4

9 回答 9

51

匿名管道

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

于 2009-02-09T15:48:08.533 回答
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);
        }
    }
    //...
}
于 2014-04-28T05:13:30.950 回答
9

我建议使用 Windows Communication Foundation:

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

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

于 2009-02-09T15:48:17.970 回答
7

WCF 上的命名管道。

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

于 2009-02-09T15:49:18.607 回答
3

还有COM

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

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

要立即开始,请转到此处...

于 2017-03-16T09:15:00.227 回答
2

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

于 2018-08-27T09:59:51.590 回答
2

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

MSDN 上有一篇出色的文章,介绍了如何使用IpcChannelRemoting 框架中的类(感谢 Greg Beech 在这里找到)来设置简单的远程处理服务器和客户端。

我建议先尝试这种方法,然后尝试将您的代码移植到 WCF(Windows 通信框架)。它有几个优点(更好的安全性、跨平台),但必然更复杂。幸运的是,MSDN 有一篇非常好的文章,用于将代码从 Remoting 移植到 WCF

如果您想立即深入了解WCF,这里有一个很棒的教程

于 2019-01-06T15:59:16.080 回答
0

死灵法

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

//out
File.AppendAllText("sharedFile.txt", "payload text here");
// in
File.ReadAllText("sharedFile.txt");
于 2020-12-15T15:24:27.490 回答