I have two console apps written with C#. I'm trying to exchange messages between them. In an attempt to do this, I'm using non-persisted memory-mapped files. In my scenario, one console app is the parent and the other is the child. Sometimes, the parent will send a message to the child. Other times, the child will send a message to the parent.
I can't figure out how to do this though. It's like each process is either listening or speaking. It's not actively doing both. At this time, I'm trying to exchange messages between the two processes using a struct
that's defined as this:
public struct Message
{
public string Source { get; set; }
public string Text { get; set; }
}
My parent console app has a method that looks like this:
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.");
}
My child console app (process) has a method that looks like this:
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
});
}
This approach isn't working. I never see the message printed to the console window. At the same time, I do not see a way to send messages back-and-forth. In my opinion, the Console.ReadKey
required in both sides locks the file.
Am I misunderstanding something? Am I using the wrong thing to exchange messages between two processes? I know I can't use Pipes for my scenario, which is why I went with memory mapped files.
Its really easy to communicate between 2 processes
For example Parent process do that :
// 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
Example of Child Process:
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
}
}
if you want child send to parent you create another EventWaithandle and do the same thing from child to Parent
Dont forget to dispose resource when process finish