Обмен сообщениями между двумя процессами C # - PullRequest
0 голосов
/ 24 октября 2018

У меня есть два консольных приложения, написанные на 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, требуемый с обеих сторон, блокирует файл.

Я что-то неправильно понимаю?Я использую неправильную вещь для обмена сообщениями между двумя процессами?Я знаю, что не могу использовать Трубы для моего сценария, поэтому я пошел с файлами, отображенными в память.

1 Ответ

0 голосов
/ 24 октября 2018

Очень просто общаться между двумя процессами

Например, родительский процесс делает это:

        // 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
        }
    }

, если вы хотитеПосылая дочерний элемент к родителю, вы создаете другой EventWaithandle и делаете то же самое от дочернего к родительскому.

Не забудьте утилизировать ресурс после завершения процесса

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...