在两个 C# 进程之间交换消息
Exchanging messages between two C# processes
我有两个用 C# 编写的控制台应用程序。我正在尝试在它们之间交换消息。为了尝试这样做,我使用了 non-persisted memory-mapped files。在我的场景中,一个控制台应用程序是 parent,另一个是 child。有时,parent 会向 child 发送消息。其他时候,child 会向 parent 发送消息。
不过我不知道该怎么做。就像每个进程要么在听,要么在说。它并没有积极地做这两件事。此时,我正在尝试使用定义如下的 struct
在两个进程之间交换消息:
public struct Message
{
public string Source { get; set; }
public string Text { get; set; }
}
我的 parent 控制台应用程序有一个如下所示的方法:
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.");
}
我的 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
});
}
此方法无效。我从来没有看到打印到控制台的消息 window。同时,我没有看到发送消息的方法back-and-forth。在我看来,双方都需要 Console.ReadKey
来锁定文件。
我是不是误会了什么?我使用错误的东西在两个进程之间交换消息吗?我知道我不能在我的场景中使用 Pipes,这就是我使用内存映射文件的原因。
2个进程之间的通信真的很容易
例如 Parent 进程执行此操作:
// 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
Child 流程示例:
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
}
}
如果你想 child 发送到 parent 你创建另一个 EventWaithandle 并从 child 到 Parent
做同样的事情
不要忘记在进程完成时释放资源
我有两个用 C# 编写的控制台应用程序。我正在尝试在它们之间交换消息。为了尝试这样做,我使用了 non-persisted memory-mapped files。在我的场景中,一个控制台应用程序是 parent,另一个是 child。有时,parent 会向 child 发送消息。其他时候,child 会向 parent 发送消息。
不过我不知道该怎么做。就像每个进程要么在听,要么在说。它并没有积极地做这两件事。此时,我正在尝试使用定义如下的 struct
在两个进程之间交换消息:
public struct Message
{
public string Source { get; set; }
public string Text { get; set; }
}
我的 parent 控制台应用程序有一个如下所示的方法:
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.");
}
我的 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
});
}
此方法无效。我从来没有看到打印到控制台的消息 window。同时,我没有看到发送消息的方法back-and-forth。在我看来,双方都需要 Console.ReadKey
来锁定文件。
我是不是误会了什么?我使用错误的东西在两个进程之间交换消息吗?我知道我不能在我的场景中使用 Pipes,这就是我使用内存映射文件的原因。
2个进程之间的通信真的很容易
例如 Parent 进程执行此操作:
// 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
Child 流程示例:
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
}
}
如果你想 child 发送到 parent 你创建另一个 EventWaithandle 并从 child 到 Parent
做同样的事情不要忘记在进程完成时释放资源