首页 > 解决方案 > 在两个 C# 进程之间交换消息

问题描述

我有两个用 C# 编写的控制台应用程序。我正在尝试在他们之间交换消息。为了做到这一点,我使用了非持久化内存映射文件。在我的场景中,一个控制台应用程序是父级,另一个是子级。有时,父母会向孩子发送消息。其他时候,孩子会向父母发送消息。

我无法弄清楚如何做到这一点。就像每个过程都在听或说。它并没有积极地做这两件事。此时,我正在尝试使用struct定义为这样的两个进程之间交换消息:

public struct Message
{
  public string Source { get; set; }

  public string Text { get; set; }
}

我的父控制台应用程序具有如下所示的方法:

private void SendMessageToChild(string text, int childHandle)
{
  Console.WriteLine("Sending message to child...");

  var messageChannelFileName = childHandle.ToString() + ".msgs";
  using (var messageChannelFile = MemoryMappedFile.CreateOrOpen(messageChannelFileName, 10240))
  {
    using (var memoryMappedAccessor = messageChannelFile.CreateViewAccessor())
    {
      var message = new Message();
      message.Text = text;
      message.Source = "Parent";

      memoryMappedAccessor.Write<Message>(0, ref message);
    }
  }

  Console.ReadKey(); // This is to keep the memory mapped file open for the child to be able to read it
  Console.WriteLine("Successfully sent message to child.");
}

我的子控制台应用程序(进程)具有如下所示的方法:

private void StartListening()
{
  Task.Run(() =>
  {
    var messageChannelFileName = Process.GetCurrentProcess().Id + ".msgs";
    using (var messageChannelFile = MemoryMappedFile.OpenExisting(messageChannelFileName, MemoryMappedFileRights.Read))
    {
      var message = new Message();
      using (var messageAccessor = messageChannelFile.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read))
      {
        messageAccessor.Read<Message>(0, out message);
        Console.WriteLine(message.Text);
      }
    }

    Console.ReadKey();  // This is to keep the memory mapped file
  });
}

这种方法行不通。我从来没有看到打印到控制台窗口的消息。同时,我看不到来回发送消息的方法。在我看来,Console.ReadKey双方都需要锁定文件。

我是不是误会了什么?我是否使用错误的东西在两个进程之间交换消息?我知道我不能在我的场景中使用管道,这就是我使用内存映射文件的原因。

标签: c#messaging

解决方案


两个进程之间的通信真的很容易

例如父进程这样做:

        // create EventWaitHandle, MemoryMapped and accessor
        ewh = new EventWaitHandle(false, EventResetMode.AutoReset, "ewhFreePIE");
        memory = MemoryMappedFile.CreateOrOpen("hookFreePIE", 68, MemoryMappedFileAccess.ReadWrite);
        accessor = memory.CreateViewAccessor();
                    :
                    :
        // Send message with accessor.write                     
        ewh.Set();//say to other process, there is something to read

子进程示例:

        memory = MemoryMappedFile.CreateOrOpen("hookFreePIE", 68, MemoryMappedFileAccess.ReadWrite);
        accessor = memory.CreateViewAccessor();
        ewh = EventWaitHandle.OpenExisting("ewhFreePIE");
        :
        :
     // sample of loop   
     public void StartLoop()
    {           
        while (running)
        {
            ewh.WaitOne();// wait Set() of another or same process
            if (cmdtostop) //you could create cmdstop inside memorymapped file (set first byte to 1 for example
            {
                running = false;
            }
            else
            {
                //do something with data , using accessor.Read
        }
    }

如果你想让孩子发送给父母,你可以创建另一个 EventWaihandle 并从孩子到父母做同样的事情

进程完成时不要忘记释放资源


推荐阅读